优点
1.提高应用程序的响应,对图形化界面更有意义,增强用户体验
2.提高计算机CPU利用率
3.改善程序结构,将既长又复杂的进程分为多个线程,独立运行,利于理解和修改
线程分类
守护线程和用户线程
java的垃圾回收就是一个典型的守护线程
守护线程是用来服务用户线程的,通过start()方法前调用Thread,setDaemon(true)可以把用户线程变成一个守护线程
当JVM中都是守护线程,当前JVM将退出
线程的状态
JDK中用Thread.State枚举表示了线程的几种状态
实现多线程,必须在主线中创建新的线程对象,java语言使用Thread类以及其子类的对象来表示线程,在它的一个完整的生命周期5种状态
Ø新建: 当一个Thread类或其子类的对象被声明并创建时,新生的线程对象处于新建状态
Ø就绪:处于新建状态的线程被start()后,将进入线程队列等待CPU时间片,此时它已具备了运行的条件
Ø运行:当就绪的线程被调度并获得处理器资源时,便进入运行状态, run()方法定义了线程的操作和功能
Ø阻塞:在某种特殊情况下,被人为挂起或执行输入输出操作时,让出 CPU 并临时中止自己的执行,进入阻塞状态
Ø死亡:线程完成了它的全部工作或线程被提前强制性地中止
线程安全问题存在的原因:
由于一个线程在操作共享数据过程中,未执行完毕的情况下,另外线程参与进来,导致共享数据存在了安全问题
解决方式
必须让一个线程共享数据完毕后,其他线程才有机会参与共享数据的操作
同步代码块
synchronized (同步监视器){
//需要被同步的代码块
}
1.共享数据,多个线程共同操作的同一个数据(变量)
2.同步监视器:由任何一个类的对象充当,哪个线程获取此监视器,谁就执行大括号里被同步的代码 俗称:锁
注意
通过继承的方式,同步监视器不能用this,因为有多个对象
可以使用static Object obj = new Object(),将obj对象作为监视器
通过实现的方式,可以用,
同步方法
synchronized在方法声明中,表示整个方法为同步方法,使用的this,仍然使用的是当前对象
public synchronized void show(String name){
//…
}
释放锁的操作
当前线程的同步方法,同步代码块执行结束
当前线程在同步代码块,同步方法中遇到break,return终止了该代码块.该方法的继续执行
当前线程在同步代码块,同步发方法找那个出现了未处理的Error或Exception,导致异常结束
当前线程在同步代码块,同步方法中执行了线程对象的**wait()**方法,当前线程暂停,并释放了锁
不会释放锁的操作
线程执行同步代码块或者同步方法时,程序调用Thread.sleep(),Thread.yield()方法,暂停当前线程的执行
线程执行同步代码块时其他线程调用了该线程的suspend()方法将该线程挂起,该线程不会释放锁(同步监视器)
尽量避免使用suspend()和resume()来控制线程