Java 多线程三:线程间的通信

线程间通信主要是以下三个方法:
 * wait notify notifyAll
 * 这三个方法定义在Object中,且都在同步代码块中使用
 * wait:令当前线程挂起并放弃CPU 同步资源,让别的线程可以访问修改共享资源
 * 当前线程排队等候再次对资源的访问
 * notify:唤醒正在排队等待的同步资源的线程中优先级最高者结束等待
 * notifyAll:唤醒正在排队等待的同步资源的所有线程
 

如下例  使用两个线程交替打印1-100


 class PrintNum implements Runnable{
    int num=1;
    @Override
    //存在线程安全问题,使用synchronized,但是这样没有进行线程间交替执行 需要用线程间的通信
    public void run() {
        while(true) {
            synchronized(this) {    
            //进行唤醒操作(此步是必须得,不然造成了死锁)
            notify();
            if(num<=100) {
                System.out.println(Thread.currentThread().getName()+":"+num);
                num+=1;
            }
            try {
                wait();//当前线程执行完 等待,记得需要唤醒,不然只打印两次
            } catch (InterruptedException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }//
            }
        }
        
    }
    
}
public class TestCom {
    public static void main(String[] args) {
        PrintNum p=new PrintNum();
        Thread t1=new Thread(p);
        Thread t2=new Thread(p);
        t1.start();
        t2.start();
    }
}
运行结果:

下面再进行一个经典的生产者和消费者的案例:

class Clerk{
    int product;
    //生产产品
    public synchronized void addProduct(){
        if(product>=20) {
            try {
                wait();
            } catch (InterruptedException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
        }else {
            product++;
            System.out.println(Thread.currentThread().getName()+"生产了"+product+"个产品");
            notifyAll();
        }
    }
    public synchronized void consumeProduct() {
        if(product<=0) {
            try {
                wait();
            } catch (InterruptedException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
        }else {
            System.out.println(Thread.currentThread().getName()+"消费了了"+product+"个产品");
            product--;
            notifyAll();
        }
    }
}
class Producer implements Runnable{
    Clerk clerk;
    public Producer(Clerk clerk) {
        this.clerk=clerk;
    }
    @Override
    public void run() {
        System.out.println("开始生产");
        while(true) {
            try {
                Thread.currentThread().sleep(1000);
            } catch (InterruptedException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
            clerk.addProduct();
        }
    }
    
}
class Customer1 implements Runnable{
    Clerk clerk;
    public Customer1(Clerk clerk) {
        this.clerk=clerk;
    }
    public void run() {
        System.out.println("消费者消费");
        while(true) {
            try {
                Thread.currentThread().sleep(1000);
            } catch (InterruptedException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
            clerk.consumeProduct();
        }
    }
}
public class TestPC {
    public static void main(String[] args) {
        Clerk clerk=new Clerk();
        Producer p1=new Producer(clerk);
        Customer1 c1=new Customer1(clerk);
        Thread t1=new Thread(p1);//生产者
        Thread t3=new Thread(p1);//生产者
        Thread t2=new Thread(c1);//消费者
        t1.setName("生产者");
        t2.setName("消费者");
        t3.setName("生产者2");
        t1.start();
        t2.start();
        t3.start();
    }
}
运行结果:

一个动态过程,因为生产者生产 消费者消费两者交替进行。

希望对大家有帮助。

猜你喜欢

转载自blog.csdn.net/qq_29750461/article/details/81222402