线程间通信:其实就是多个线程操作同一个资源,但是操作的动作不同。
通过一个需求来演示两种通信方式:
有一个共享资源类Resource,有一个生产者,一个消费者,每生产一个就消费一个。
第一种:
class Resource{//这是一个共享资源类。
private String name;
private int count=1;
private boolean flag = false;//定义一个判断标记
public synchronized void set(String name){
while(flag){//是用while的原因:被唤醒的线程在判断一次标记。if只判断一次。
try {
this.wait();//flag为true的时候,就等待。
} catch (Exception e) {
e.printStackTrace();
}
}
this.name=name+"--"+count++;
System.out.println(Thread.currentThread().getName()+"....生成者.."+this.name);
flag = true;//将flag设置为true
this.notifyAll();//唤醒等待的所有线程。notify()只能唤醒一个线程,可能导致程序中的所有线程都等待。
}
public synchronized void get(){
while(!flag){//当flag 等于false的时候,就等待。
try {
this.wait();
} catch (Exception e) {
e.printStackTrace();
}
}
System.out.println(Thread.currentThread().getName()+"....消费者........."+this.name);;
flag = false;//将flag设置为false
this.notifyAll();//唤醒所有等待的线程。
}
}
class Producer implements Runnable{//创建一个生产者的线程。
private Resource r ;
public Producer(Resource r) {
this.r = r;
}
public void run(){
while(true){
r.set("+商品+");
}
}
}
class Consumer implements Runnable{//创建一个消费者的线程。
private Resource r ;
Consumer(Resource r){
this.r = r;
}
public void run(){
while(true){
r.get();
}
}
}
public class Demo19 {
public static void main(String[] args) {
Resource r = new Resource();
Producer p = new Producer(r);
Consumer c = new Consumer(r);
new Thread(p).start();
new Thread(c).start();
new Thread(p).start();
new Thread(c).start();
}
}
第二种方式:在JDK1.5提供了多线程的升级解决方案,将synchronized替换成了显示的Lock操作;将Object中的wait,notify, notifyAll替换成了Condition对象的await,signal,signalAll,该对象可以通过Lock获取。通过该方法可以实现本方只唤醒对方的 操作。
import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;
class Resource1{
private String name;
private int count=1;
boolean flag = false;
private Lock lock = new ReentrantLock();//创建一个锁
private Condition condition_pro = lock.newCondition();//创建一个生产者的Condition对象。Object类的替代类。
private Condition condition_con = lock.newCondition();//创建一个消费者的Condition对象。
public void set(String name)throws InterruptedException{
lock.lock();//上锁
try{
while(flag){
condition_pro.await();//如果flag为true,生产者线程就等待。
}
this.name = name+"--"+count++;
System.out.println(Thread.currentThread().getName()+"...生产者..."+this.name);
flag = true;
condition_con.signal();//唤醒消费者线程。
}finally{
lock.unlock();//解锁
}
}
public void get()throws InterruptedException{
lock.lock();//上锁
try{
while(!flag){
condition_con.await();//如果flag为flase,消费者线程就等待
}
System.out.println(Thread.currentThread().getName()+"...消费者........."+this.name);
flag = false;
condition_pro.signal();//唤醒生产者线程。
}finally{
lock.unlock();//解锁
}
}
}
class Producer1 implements Runnable{
private Resource1 r ;
public Producer1(Resource1 r) {
this.r = r;
}
public void run(){
while(true){
try {
r.set("+商品+");
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
class Consumer1 implements Runnable{
private Resource1 r;
Consumer1(Resource1 r){
this.r = r;
}
public void run(){
while(true){
try {
r.get();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
public class Demo20 {
public static void main(String[] args) {
Resource1 r = new Resource1();
new Thread(new Producer1(r)).start();
new Thread(new Consumer1(r)).start();
new Thread(new Producer1(r)).start();
new Thread(new Consumer1(r)).start();
}
}