多线程简单介绍

-

Thread 与 Runnable的比较

  • Thread需要继承实现,而Java中是单继承,所以我一般不常用Thread,而是使用Runnable接口实现多线程

关于多线程的几个方法

  • sleep():让当前线程进入休眠状态(线程不会释放获得的锁),参数设置休眠时间。
  • yield():让步,让不低于自己优先级的线程有机会运行。(不会释放获取的锁

  • interrupt():终止哪些调用中断方法进入阻塞状态的线程。(sleep,wait,join都是中断方法

  • join(): 当前线程对一个线程调用此方法,当前线程就会停止运行,直到另一个线程执行完成后,才会继续执行当前线程。(会释放获得的锁,join方法内部调用了wait方法

  • wait():此方法是object的实例方法,让当前线程进入阻塞状态。(释放获取对象的内部锁)可通过notify和notifyall来唤醒

  • notify()/notifyall():是Object的实例方法,notify()是唤醒等待该对象的线程,而notifall()是唤醒所有等待的对象。

synchronized关键字

  • Java中的每个对象都有一个内部锁,每个类都有一个锁,控制多线程对其静态成员的并发访问。如果一个实例方法使用synchronized关键字修饰,内部锁就会监听这个方法,只有获取到该对象内部锁的线程才能执行此方法。
  • 对象的内部锁在同一时刻只能由一个线程持有,其他线程尝试获取该对象内部锁都会被阻塞,这种情况下的阻塞不会被中断。

volatile域

  • 此关键字可以保证实例域是可见的,通常当我们访问内存中的变量时,就会把它缓存在寄存器中,当需要读这个值时,直接从寄存器拿取,进行加减运算时,直接将寄存器中的值进行加减运行,结束后将值写回内存,问题就出来了,对一个线程对flag变量进行操作,先将flag放进寄存器中,准备将它加上2,这个时候,另一个线程抢占了资源,对flag值进行操作,进行了加3的操作,并将flag写回了内存,这时,第一个线程对flag继续进行操作,对原来的flag值进行操作,加2,然后写回内存,当我们读取时就会发现,flag值为2,所以volatile就是为了解决该问题,就是每次访问变量时,直接从内存拿值,而不会从寄存器中获取。
参考资料