什么是多线程之间通讯?
多线程之间通讯,其实就是多个线程在操作同一个资源,但是操作的动作不同。
用notify()和wait()方式实现通讯。
wait、notify方法
1.因为涉及到对象锁,他们必须都放在synchronized中来使用. Wait、Notify一定要在synchronized里面进行使用。
2.Wait必须暂定当前正在执行的线程,并释放资源锁,让其他线程可以有机会运行
3. notify/notifyall: 唤醒因锁池中的线程,使之运行
注意:一定要在线程同步中使用,并且是同一个锁的资源
废话不多说,代码演示。场景比较简单,生产者生产一个零件,消费者消费一个零件。
//共享对象,零件
class Component{
// 姓名
public String name;
// 编号
public String type;
// 为true情况下 允许读,不能写
// 为false情况下 允许写,不能读。
public boolean flag = false;
}
//生产线程
class InThread extends Thread{
public Component component;
public InThread(Component component) {
this.component = component;
}
@Override
public void run() {
int count = 0;
while (true){
synchronized (component){
if(component.flag){
//允许读,不能写,释放锁对象
try {
component.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
if (count == 0) {
component.type = "A";
component.name = "零件"+count;
} else {
component.type = "B";
component.name = "零件"+count;
}
count = (count + 1) % 2;// 0 1 0 1 0 1
// 标记当前线程为等待
component.flag =true;
// 唤醒被等待的线程
component.notify();
}
}
}
}
//消费线程
class OutThread extends Thread{
public Component component;
public OutThread(Component component) {
this.component = component;
}
@Override
public void run() {
while(true){
synchronized (component){
if(!component.flag){
//允许写,不能读,释放锁对象
try {
component.wait();
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
System.out.println(component.name + "," + component.type);
// 标记当前线程为等待
component.flag = false;
// 唤醒被等待的线程
component.notify();
}
}
}
}
public class Test {
public static void main(String[] args) {
Component component = new Component();
Thread inThread = new InThread(component);
Thread outThread = new OutThread(component);
inThread.start();
outThread.start();
}
}
wait与sleep区别
1、sleep()方法属于Thread类,而wait()方法,则是属于Object类
2、sleep()方法导致了程序暂停执行指定的时间,让出cpu给其他线程,但是他的监控状态依然保持者,当指定的时间到了又会自动恢复运行状态。在调用sleep()方法的过程中,线程不会释放对象锁。
而当调用wait()方法的时候,线程会放弃对象锁,进入等待此对象的等待锁定池,只有针对此对象调用notify()方法后,本线程才进入对象锁定池准备,获取对象锁进入运行状态。