线程间的通信就是指不同线程间针对同一资源的操作和处理过程。
下面是个通过等待唤醒机制来进行生产和消费学生类的案例:
学生类:
public class Student {
String name;
boolean flag;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public boolean isFlag() {
return flag;
}
public void setFlag(boolean flag) {
this.flag = flag;
}
}
生产者线程(生产学生类):
public class SetThread implements Runnable {
private Student s;
private int x=0;
public SetThread(Student s) {
this.s = s;
}
@Override
public void run() {
// TODO Auto-generated method stub
while(true) {
synchronized(s){
if(s.flag) s.wait();//进入等待,会释放锁
s.name="kobe";//赋值后需要被消费
s.flag=true;//循环需要先暂停,等待被消费Student数据
s.notify();//唤醒消费线程,唤醒后不代表消费线程可立即执行,还要抢CPU
}
}
}
}
消费者线程(消费学生类):
public class GetThread implements Runnable {
private Student s;
public GetThread(Student s) {
super();
this.s = s;
}
@Override
public void run() {
// TODO Auto-generated method stub
while(true) {
synchronized(s) {
if(!s.flag) s.wait();//进入等待,会释放锁,醒来也是从这醒来
System.out.println(s.name);//被唤醒可以去消费student的值
s.flag=false;//循环需要先暂停,等待被生产的Student数据
s.notify();//唤醒生产线程
}
}
}
}
测试Demo:
public class CommitDemo {
public static void main(String[] args) {
// TODO Auto-generated method stub
Student s=new Student();
SetThread st=new SetThread(s);
GetThread gt=new GetThread(s);
Thread t1=new Thread(st);
Thread t2=new Thread(gt);
t1.start();
t2.start();
}
}
wait()方法是在一个已经进入了同步锁的线程内,让自己暂时让出同步锁,以便其他正在等待此锁的线程可以得到同步锁并运行,只有其他线程调用了notify()方法才可以重新获得CPU执行资格,它们都是用在同步代码块里的,用同步代码块的对象来调用这两个方法,可实现线程间的合作,一个线程等另一个线程,并唤醒它,适合针对同一个资源上的协同操作。