基本储备:
关于进程和线程的概念就不多说了,有兴趣可以看线程与进程之小球游戏。
它们的本质区别是:每个进程拥有自己的一套变量,而线程只是共享数据。所以自然的也就可以理解为什么要引入多线程,因为线程间的切换可以减少开销。可以把线程间的切换看作是车在一条路的不同车道之间换道,而进程则看成是每一条不同的路。
多进程的意义:提高CPU的使用率。 多线程的意义:提高应用程序的效率。
创建多线程的三种基本方式:
①继承Thread类,重写run方法,自定义类的实例,调用start()方法启动线程。
②实现Runnable接口。
③采用Excuter创建线程池。
启动线程start方法和run方法的区别:
run方法里面写要线程执行的代码,但不能调用run 方法(这样的效果和对象调用方法一样,最终还是运行在主线程中),只有用start的方法才是启动一个线程,然后jvm在通过线程调用run方法。
start的方法只能调用一次,如果对一个线程对象多次调用start方法的话,会产生:IllegalThreadStateException异常。
还有让一个线程停止,其实就是让run方法里面的代码停止执行。一般不用stop()方法(这是强行停止线程),而用一个标记标识线程状态。
wait()方法和sleep()方法:
相同点:
1.在多线程环境下调用可阻塞指定的秒数,并返回。
2.两者都可以调用interrupt()方法打断线程的暂停状态
不同点:
1. sleep是线程类(Thread)的方法,调用会暂停此线程指定的时间,它仅仅释放CPU资源或者让当前线程停止执行一段时间,但监控依然保持,不会释放对象锁,到时间自动恢复。wait是Object的方法,释放了锁,进入等待队列,待调用notify唤醒指定的线程或者notifyAll唤醒所有线程,才会进入锁池,当获得对象锁,进入运行状态。(每个对象都有一个锁来控制同步访问,Synchronizad关键字可以和对象的锁交互,来实现线程的同步。)
2.wait,notify,notifyAll只能在同步方法或者同步控制块中使用,而sleep方法可以在任何地方使用。
3.sleep必须捕获异常,而wait,notify,notifyAll不需要捕获异常。
要了解线程中的方法查看API的Thread类。
线程的状态:
新建状态(New):
用new语句创建的线程处于新建状态,此时它和其他Java对象一样,仅仅在堆区中被分配了内存。
就绪状态(Runnable):
当一个线程对象创建后,其他线程调用它的start()方法,该线程就进入就绪状态,Java虚拟机会为它创建方法调用栈和程序计数器。处于这个状态的线程位于可运行池中,等待获得CPU的使用权。
运行状态(Running):
处于这个状态的线程占用CPU,执行程序代码。只有处于就绪状态的线程才有机会转到运行状态。
阻塞状态(Blocked):
阻塞状态是指线程因为某些原因放弃CPU,暂时停止运行。当线程处于阻塞状态时,Java虚拟机不会给线程分配CPU。
死亡状态(Dead):
当线程退出run()方法或异常终止时,就进入死亡状态,该线程结束生命周期。