多线程之间通讯
什么是多线程通讯?
就是多个线程对同一个共享资源,进行不同的操作。
介绍两个API中的方法,这两个是Object里面的方法:
wait();等待,线程从运行状态变为休眠状态
notify();唤醒,线程从休眠状态变为运行状态
现在解决一下这样一个案例:
两个线程,面向一个仓库进行读写操作,仓库里面用一个用户类表示,里面包括姓名和性别这两个属性,A线程往里面写,然后B线程立马读出来,这样交替执行,该怎么设计?
分析一下这个题目:仓库里面是两个属性,两个线程同时对仓库进行操作,肯定要同步,不然会出现数据混乱问题,然后考虑的是让两个线程交替执行,A线程写完后要等待B线程读出以后在继续写,这时候要用到线程之间的通讯。wait和notify的使用必须与synchronized一起使用,wait包括释放锁,并进入阻塞队列这两个语义,这两步需要指定一个监视器来完成;notify是唤醒该线程,要想唤醒,首先需要知道该对象在哪儿,需要获取该对象的锁,才能去该对象对应的等待队列去唤醒一个线程,只有已经释放该对象锁的线程,才能被唤醒然后去竞争该对象锁。
为了更好的看出效果,我让写线程奇数和偶数是写入不同的姓名和性别,看是否打印会出现数据混乱。
代码如下:
class User { String name; String sex; boolean flag = true; } class Write extends Thread { User user; public Write(User user) { this.user = user; } @Override public void run() { int count = 2; while (true) { synchronized (user) { if (!user.flag) { try { user.wait(); } catch (InterruptedException e) { // TODO Auto-generated catch block e.printStackTrace(); } } if (count % 2 == 0) { user.name = "周瑜"; user.sex = "男"; } else { user.name = "小乔"; user.sex = "女"; } count = (count + 1) % 2; user.notify(); user.flag = false; } } } } class Read extends Thread { User user; public Read(User user) { this.user = user; } @Override public void run() { while (true) { synchronized (user) { if (user.flag) { try { user.wait(); } catch (InterruptedException e) { e.printStackTrace(); } } System.out.println(user.name + "," + user.sex); user.notify(); user.flag = true; } } } } public class OutInputDemo { public static void main(String[] args) { User user = new User(); Write write = new Write(user); Read read = new Read(user); write.start(); read.start(); } }