多线程方法学习
博客贡献阅读:
1:多线程的学习:https://blog.csdn.net/xingjing1226/article/details/81977129
2:对象锁释放:https://www.jianshu.com/p/ffc0c755fd8d,关于notify以及wait是否释放锁的问题
3:锁对象和wait()方法不一致导致的问题:https://blog.csdn.net/fangaiming1/article/details/107532472
1、yield的使用
线程调用yield会让线程进入就绪状态,重新争夺资源,有可能会被其他线程获取,也有可能还是自己获取到线程资源
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
public static void main(String[] args) { Thread oneThread = new Thread(new Runnable() { @Override public void run() { for (int i=1;i<10;i++){ if (i == 5){ Thread.yield(); } System.out.println(Thread.currentThread().getName()+"i=="+i); } } },"one"); Thread twoThread = new Thread(new Runnable() { @Override public void run() { for (int i=1;i<10;i++){ System.out.println(Thread.currentThread().getName()+"i=="+i); } } },"two"); oneThread.start(); twoThread.start(); }
如上:线程one可能还会重新获取到资源,也有可能被线程two获取到资源,主要看他们之间的相互竞争
2、sleep()的使用,同join一样
线程调用sleep方法,会让线程处于等待状态,等到等待事件过后,重新进入就绪状态,等待获取资源执行
3、wait()/notify方法的使用
注意:wait方法必须配合synchronized一起使用,因为涉及到线程之间的通信,必须得有一个锁机型控制,阻塞某个线程,不然
就会出现时间片轮询得操作了,就不会有线程之间的通信了,可以看上面博客,线程锁释放
错误示范:
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
public class ShoesTest { public static void main(String[] args) { Shoes shoes = new Shoes(); new Thread(new Runnable() { @Override public void run() { synchronized (Shoes.class) { while (true) { if (shoes.getNum() == 0) { try { System.out.println("进入等待程序"); shoes.wait(); } catch (Exception e) { e.printStackTrace(); } } shoes.subNum(); System.out.println("消费一双鞋"); //shoes.notify(); } } } }).start(); new Thread(new Runnable() { @Override public void run() { synchronized (Shoes.class) { while (true) { if (shoes.getNum() > 0) { try { shoes.notify(); }catch (Exception e){ e.printStackTrace(); } } shoes.addNum(); System.out.println("生产一双鞋"); //shoes.notify(); } } } }).start(); } }
上面存在两个问题:
第一:锁对象是Class而非对象,这回引发异常问题,导致wait不进入阻带,可以惨遭2,和3这两篇博客看
第二:notify并不会立马释放锁,会等代码块执行完成以后才会释放锁的,所以当锁对象换成shoes的时候,会一直执行第二个线程
无法从while(true)中醒过来
正确的实列:
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
public class ShoesTest { public static void main(String[] args) { Shoes shoes = new Shoes(); new Thread(new Runnable() { @Override public void run() { synchronized (Shoes.class) { while (true) { if (shoes.getNum() == 0) { try { System.out.println("进入等待程序"); shoes.wait(); } catch (Exception e) { e.printStackTrace(); } } shoes.subNum(); System.out.println("消费一双鞋"); shoes.notify(); } } } }).start(); new Thread(new Runnable() { @Override public void run() { synchronized (Shoes.class) { while (true) { if (shoes.getNum() > 0) { try { shoes.wait(); }catch (Exception e){ e.printStackTrace(); } } shoes.addNum(); System.out.println("生产一双鞋"); shoes.notify(); } } } }).start(); } }
保证使用wait释放当前锁,退出while(true)循环
一张图来总结线程的流转状态: