线程通信(生产者消费者问题)

线程通信(生产者消费者问题)

**线程通讯指的是:**多个线程通过消息传递实现相互牵制,相互调度,即线程间的相互作用。

涉及三个方法:
.wait一旦执行此方法,当前线程就进入阻塞状态,并释放同步监视器(锁)
.notify一旦执行此方法,**就会唤醒被wait的一个线程。**如果有多个线程被wait,就唤醒优先级高的那个。
.notifyAll一旦执行此方法,就会唤醒所有被wait的线程。

说明:
.wait(),notify(),notifyAll()三个方法必须使用在同步代码块或同步方法中。
.wait(),notify(),notifyAll()三个方法是定义在java.lang.Object类中(注意调用它的类)

1.实现线程交替执行

1.用Lock锁实现

import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;

//用Lock锁实现线程交替输出
public class ThreadDemo extends Thread {
    static int num = 0;
    static Lock lock = new ReentrantLock();
    static Condition con = lock.newCondition();
//当使用lock锁实现线程同步时,要实现Condition类(static Condition con = lock.newCondition();)
    @Override
    public void run() {
        while (true) {
            lock.lock();
            con.signal();//线程唤醒
            if (num < 100) {
                num++;
                System.out.println(Thread.currentThread().getName() + ":" + num);
            }
            try {
                con.await();//线程阻塞
                lock.unlock();
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }
}

如果在lock锁中执行con.signal();//线程唤醒与con.await();//线程阻塞的方法,

需要实现Condition类(Condition con = lock.newCondition();)否则会出现异常

2.经典例题:生产者/消费者问题

生产者(Productor)将产品放在柜台(Counter),而消费者(Customer)从柜台处取走产品,生产者一次只能生产固定数量的产品(比如:1), 这时柜台中不能再放产品,此时生产者应停止生产等待消费者拿走产品,此时生产者唤醒消费者来取走产品,消费者拿走产品后,唤醒生产者,消费者开始等待

解题思路:①先定义一个柜台类,在柜台类中确定商品的变量,写入生产者生产商品的方法add(),在写入消费者消费商品的方法sub()


public class Counter {
    static   int num=0;//柜台商品数
  static Lock lock=new ReentrantLock();
  static Condition con=lock.newCondition();

    //生产者生产
  public void add(){
        lock.lock();
        con.signal();
        if (num==0){
            num++;
            System.out.println("生产者生产");
        }else{
            try {
           con.await();
           lock.unlock();
            } catch (InterruptedException e) {
                lock.unlock();
            }
        }
    }

//消费者消费
    public void sub(){
        lock.lock();
        con.signal();
        if (num==1){
            num--;
            System.out.println("消费者消费");
        }else{
            try {
                con.await();
                lock.unlock();
            } catch (InterruptedException e) {
                lock.unlock();
            }
        }
    }

}

②生产者类继承Thread类,重写run方法,调用add方法,创建含参的构造方法(确保两个线程用的是一个柜台)


public class Productor extends  Thread{
    Counter c;

    public Productor(Counter c) {
        this.c = c;
    }


    @Override
    public void run() {
        while (true){
            try {
                Thread.sleep(1000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            c.add();
        }
    }
}

③消费者同理


public class Customer extends Thread {
    Counter c;

    public Customer(Counter c) {
        this.c = c;
    }

    @Override
    public void run() {
        while (true){
            try {
                Thread.sleep(500);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            c.sub();
        }


    }
}

④测试类


public class Test {
    public static void main(String[] args) {
        Counter c=new Counter();
        Customer customer=new Customer(c);
        Productor productor=new Productor(c);
        customer.start();
        productor.start();
    }
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值