什么是多线程之间的通讯? 就是多个线程在操作同一个资源,但是操作的动作不同。
package com;
class Printer{
// 打印机
public String fileName;
public String fileType;
// true: 生产者正在生产数据,消费者应该进入休眠状态
// false:消费者正在消费数据,生产者应该进入休眠状态
boolean flag = true;
}
// wait和notify方法要在线程同步中使用
// wait,notify, notifyAll方法都是Object里的方法,用来控制线程的状态
// wait: 让持有该对象的线程把该对象的控制权交出去,然后处于等待状态。
// notify: 通知某个正在等待这个对象的控制权的线程可以继续运行。
class Out extends Thread{
Printer print;
public Out(Printer print){
this.print = print;
}
@Override
public void run() {
int count = 0;
while(true){
synchronized (print) {
System.out.println("生产者:"+print.flag);
if(!print.flag){
try {
print.wait(); // 消费者正在消费,生产者应该休眠
// 当执行完wait方法后,该线程就进入休眠,下面的代码就不会被执行
} catch (InterruptedException e) {
e.printStackTrace();
}
}
//System.out.println("生产者:"+print.flag);
if(count == 0){
print.fileName = "三国演义";
print.fileType = "pdf";
}else{
print.fileName = "红楼梦";
print.fileType = "txt";
}
count = (count + 1)%2;
print.flag = false;
//System.out.println("生产者生产完毕");
print.notify();
}
}
}
}
class Input extends Thread{
Printer print;
public Input(Printer print){
this.print = print;
}
@Override
public void run() {
while(true){
synchronized (print) {
//System.out.println("消费者:"+print.flag);
if(print.flag){
try {
print.wait(); // 生产者正在生产,消费者应该休眠
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
System.out.println(print.fileName+", "+print.fileType);
print.flag = true;
print.notify(); // 消费消费完毕, 唤醒生产者
//System.out.println("消费者消费完毕");
}
}
}
}
public class OutInputThread extends Thread{
public static void main(String[] args){
Printer print = new Printer();
Out out = new Out(print);
Input input = new Input(print);
out.start();
input.start();
}
}
wait和sleep的区别:
wait可以释放锁的资源,而sleep不会释放资源
wait需要notify才能从休眠状态变为运行状态。sleep时间到期,会自动从休眠状态到运行状态。