一、线程的概念
1、线程:线程是操作系统能够进行运算调度的最小单位,是进程中独立运行的子任务即线程是进程中的实际运作单位;一个进程中可以并发多个线程,每条线程并行执行不同的任务。同一进程中的多条线程将共享该进程中的全部系统资源, 所以线程之间互相通信不必像进程通信那么麻烦(调用内核),直接利用共享资源就可以实现通信, 但每个线程有各自的调用栈(call stack),自己的寄存器环境(register context),自己的线程本地存储(thread-local storage)
2、为什么使用多线程
- 多处理器系统:合理使用线程可以发挥多处理器的处理能力,提高系统吞吐量(例如一个拥有10个处理器的系统,多线程可以做到10个线程并行执行)
- 对于单核处理器,多线程也可以提升系统吞吐量;单线程时如果执行中遇到同步I/O操作,则处理器将处于空闲状态;如果采用多线程,CPU可以将时间片切换到非阻塞的线程中继续执行任务;即程序可以在IO阻塞期间继续工作,处理器也一直处于工作状态。
二、使用线程
方式一:继承Thread 类重新run()方法
结果:
- 当前线程名:main
- 当前线程名:Thread-0
方法二:实现Runnable 接口,实现run( )方法
结果:
- 当前线程名:main
- 当前线程名:Thread-0
由结果可知当前程序有两个线程 main线程 和Threa-0线程;所以java中程序的入口main()方法本身就是一个线程名为main的线程
三、Thread 中的start方法与run方法
调用start()方法,才是开启多线程的正确姿势,调用该方法后,使线程进入可运行状态;程序将继续向后执行,何时执行run方法的逻辑,则取决于该线程何时获得到CPU的时间片,使自己进入运行状态,run方法会在JVM中调用
run方法,从Thread类本身来讲,他就是一个普通方法,如果我们在JAVA代码中直接调用 new Thread().run();则就是普通的方法调用,程序本身并没有实现多线程,依旧是串行阻塞形式。
start()方法源码:
public synchronized void start() {
//先验证该线程是否是初始化状态 (A zero status value corresponds to state "NEW")
if (threadStatus != 0){
throw new IllegalThreadStateException();
}
//将线程加入线程组
group.add(this);
boolean started = false;
try {
//调用一个本地方法
start0();
//启动成功,标识为启动状态 true
started = true;
} finally {
try {
//如果没开启,标识为启动失败
if (!started) {
group.threadStartFailed(this);
}
} catch (Throwable ignore) {
}
}
}
1、private volatile int threadStatus = 0; 这个状态在start方法中主要控制同一个线程只能启动一次,既一个线程只有在初始化状态才能调用start()方法,否则抛出异常。start()是一个线程同步方法;
2、private native void start0();
线程是操作系统能够进行运算调度的最小单位,所以编程语言本身是无法操作线程的,需要JVM调用操作系统函数。