目录导引:
一、上下文切换
CPU通过时间片分配算法给每个线程分配时间片来执行,时间片一般是几十毫秒。切换线程前会保存上一个线程的状态,以便下次切换回来时可以再加载这个线程的状态。
线程从保存到再加载的过程就是一次上下文切换。
二、什么是进程?
进程是一个执行中的程序。(本文章只限于讨论java进程和java线程)
一个进程由一个或多个线程组成,各个进程间互不干扰。进程有独立的内存,在Java虚拟机规范中称为java堆,习惯称堆内存,随着java虚拟机的启动而创建,存储所有对象实例和数组对象,并内置垃圾收集器。
进程的创建可参考RunTime的exec()方法或ProcessBuilder的start()方法。
三、什么是线程?
线程是操作系统能够调度的最小单位。
一个进程中的所有线程共享堆内存。每个线程也有单独的内存,习惯称栈内存,随着线程的创建而创建。线程执行一个方法时会创建一个栈帧来存储方法信息、局部变量、引用变量等。每一个方法从调用到执行完成的过程,就对应
栈帧从入栈到出栈的过程。
如何创建线程?
1、实现Runnable接口
package com.myconcurrent.test; public class MyRunnable implements Runnable { public void run() { System.out.println("我的线程ID:" + Thread.currentThread().getId()); } public static void main(String[] args) { Thread thread = new Thread(new MyRunnable()); System.out.println("主线程ID:" + Thread.currentThread().getId()); //1 thread.start(); //2 thread.run(); //3 System.out.println("主线程ID:" + Thread.currentThread().getId()); //4 } } 运行结果: 主线程ID:1 我的线程ID:1 主线程ID:1 我的线程ID:11
运行结果:第一行是位置1的日志,第二行是位置3的日志,直接调用run方法并不会创建新线程去执行,只是普通的方法调用,第三行是位置4的日志,第四行是位置2的日志,start()方法会创建新线程去执行任务(调用run方法),需要额外的时间,但是并不会阻塞主线程的执行。
2、继承Thread类
package com.myconcurrent.test; public class MyThread extends Thread { @Override public void run() { System.out.println("我的线程ID:" + Thread.currentThread().getId()); } public static void main(String[] args) { new MyThread().start(); System.out.println("主线程ID:" + Thread.currentThread().getId()); } } 运行结果: 主线程ID:1 我的线程ID:11
运行结果:ID不一样,说明也创建了新线程,写法上来看,继承Thread类更简洁一点,但是java只支持单继承(某些内部类情况不讨论),如果需要继承别的类,则可选择实现Runnable接口。源码上可以看到Thread类实现了Runnable接口。
如有疑问欢迎提出,如有错误欢迎指正。
转载请注明本文地址:http://www.cnblogs.com/yqxx1116/p/8530233.html