Java 多线程的综合运用

 栗子:

实现目标:

   生产者/消费者问题

    此题目需实现一个生产者,店员,消费者之前程序.生产者生产产品,生产好之后交给店员,店员只能持有固定数量的产品,店员与生产者之间保持信息交流,即店员持有的产品数量小于所需持有的固定数量时,生产者开始生产产品至固定数量而后停止生产;消费者与店员之间也保持信息交流,消费者每消费一个产品,店员持有的产品数量减少相应的数目,如此往复循环

分析问题:

  1.是否是多线程? 是,生产者线程,消费者线程

  2.是否存在线程安全问题(是否共享数据)? 是,店员或产品

  3.如何解决线程安全问题/ 同步机制,三种方法

  4.是否设计线程通信? 是

代码实现:

   首先利用面向对象的设计思想,因为店员与生产者及消费者都有交流,不妨将店员设为两者沟通的桥梁,设置一个Cleck类,在该类中分别声明生产产品和消费产品的方法

class  Clerk{

    private int producount = 0;    //设置初始产品数量为0

    //生产产品
    //声明生产产品的方法,使用synchronized同步方法的方式解决线程安全问题
    public synchronized void produceProduct(){
        if (producount < 20){    //判断店员持有的产品数量是否超过20,若小于则生产产品
            producount ++;
            System.out.println(Thread.currentThread().getName()+",开始生产第"+producount+"个产品");
            notify();    //调用notify()方法唤醒阻塞的线程
        }else{
            //等待
            try {
                wait();   //产品数量超过20时,调用wait()方法,使线程进入阻塞状态,等待消费者消费产品,从而实现线程间的通信问题,此时需使用try{ }catch{ }语句,处理异常
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }

    //消费产品
    //声明消费产品的方法,使用synchronized同步方法的方式解决线程安全问题
    public synchronized void ConsumeProduct(){
        if (producount > 0){    //判断店员持有的产品数量是否大于0,若大于则可以消费产品
            System.out.println(Thread.currentThread().getName()+",开始消费第" +producount+"个产品");
            producount--;
            notify();    //调用notify()方法唤醒阻塞的线程
        }else{
            //等待
            try {
                wait();   //产品数量小于等于0时,调用wait()方法,使线程进入阻塞状态,等待生产者生产产品,从而实现线程间的通信问题,此时需使用try{ }catch{ }语句,处理异常
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }

}

再分别声明生产者类和消费者类

class producer extends Thread{     //声明生产者类,继承Thread
      private Clerk clerk;
      public producer(Clerk clerk){
          this.clerk=clerk;
      }

    @Override
    public void run() {
        System.out.println(getName() + ":开始生产...");
        while (true){
            try {
                Thread.sleep(5);   //调用sleep()方法,控制线程等待的时间,此时使用try{ }catch{ }语句,处理异常
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            clerk.produceProduct();   //调用clerk类中生产产品的方法
        }
    }
}

class consume extends Thread{    //声明消费者类,继承Thread
    private Clerk clerk;
    public consume(Clerk clerk){
        this.clerk=clerk;
    }

    @Override
    public void run() {
        while (true){
            try {
                Thread.sleep(10);   //调用sleep()方法,控制线程等待的时间,此时使用try{ }catch{ }语句,处理异常
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            clerk.ConsumeProduct();   //调用clerk类中消费产品的方法
        }
    }
}

最后在main方法中创建线程对象及调用开始方法,使线程运行

public class ProductTest {

    public static void main(String[] args) {

        Clerk clerk = new Clerk();    //创建Clerk类的对象

        producer p1 = new producer(clerk);    //将创建的clerk对象赋给producer方法,并创建producer对象
        p1.setName("生产者1");

        consume c1 = new consume(clerk);      //将创建的clerk对象赋给consume方法,并创建consume对象
        c1.setName("消费者1");
        consume c2 = new consume(clerk);
        c2.setName("消费者2");

        p1.start();   //调用start()方法,使线程开始执行
        c1.start();
        c2.start();

    }
}

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

不会写代码的菜

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值