1、同步线程状态图
2、怎么实现同步
线程间的相互作用
wait and notify
The pools:
Wait pool
Lock pool
3、实例
场景: 常量number,当number是1是可以进行减1操作,当number为0时可以进行加1操作
1)Sample类
public class Sample { private int number; public synchronized void increase(){ while(number != 0){ try { wait(); } catch (InterruptedException e) { e.printStackTrace(); } } number++; System.out.println(number); notify(); } public synchronized void decrease(){ while(number == 0){ try { wait(); } catch (InterruptedException e) { e.printStackTrace(); } } number--; System.out.println(number); notify(); } }
2)IncreaseThread 线程
public class IncreaseThread extends Thread { private Sample sample; public IncreaseThread (Sample sample) { this.sample = sample; } @Override public void run() { for(int i = 0; i<20; i++){ try { Thread.sleep((long)(Math.random() * 1000)); } catch (InterruptedException e) { e.printStackTrace(); } sample.increase(); } } }
3)、DecreaseThread 类
public class DecreaseThread extends Thread { private Sample sample; public DecreaseThread (Sample sample) { this.sample = sample; } @Override public void run() { for(int i = 0; i<20; i++){ try { Thread.sleep((long)(Math.random() * 1000)); } catch (InterruptedException e) { e.printStackTrace(); } sample.decrease(); } } }
4) 测试
public class MainTest { public static void main(String[] args) { Sample sample = new Sample(); Thread t1 = new IncreaseThread(sample); Thread t2 = new DecreaseThread(sample); Thread t3 = new IncreaseThread(sample); Thread t4 = new DecreaseThread(sample); t1.start(); t2.start(); t3.start(); t4.start(); } }
5)执行结果
1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0
4、总结
1)wait与notif方法都是定义在Object类中,而且是final的,因此会被所有的Java类所继承并且无法重写。这两个方法要求在调用线程应该已经获得了对象的锁,因此对这两个方法的调用需要放在synchronized方法或块中。当线程执行了wait方法时,它会释放掉对象的锁。
2)另一个会导致线程暂停的方法就是Thread类中的sleep方法,它会导致线程睡眠指定的毫秒数,但线程在睡眠的过程中是不会释放掉对象的锁的。