java生产者消费者问题(线程同步与线程等待的应用)

Wesley13
• 阅读 577

生产者

/**
 * 类说明:生产者
 * 
 * @author 作者: user
 * @version 创建时间:2011-4-5 下午01:48:11
 */
public class Producer implements Runnable {
    private SyncStack ss;
    private int num;
    private static int counter = 1;
    public Producer(SyncStack ss) {
        this.ss = ss;
        num = counter++;
    }
    @Override
    public void run() {
        char c;
        for (int i = 0; i < 10; i++) {
            c = (char) (Math.random() * 26 + 'A');
            ss.push(c);//向堆栈中添加数据
            System.out.println("生产者 " + num + ": " + c);
            try {
                Thread.sleep((int) (Math.random() * 300));
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }
}

消费者

/**
 * 类说明:消费者
 * 
 * @author 作者: user
 * @version 创建时间:2011-4-5 下午01:56:18
 */
public class Consumer implements Runnable {
    private SyncStack ss;//堆栈对象
    private int num;
    private static int counter = 1;
    public Consumer(SyncStack ss) {
        this.ss = ss;
        num = counter++;
    }
    @Override
    public void run() {
        char c;
        for (int i = 0; i < 10; i++) {
            c = ss.pop();//从堆栈中取数据
            System.out.println("消费者 " + num + ": " + c);
            try {
                Thread.sleep((int) (Math.random() * 200));
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }
}

堆栈类

import java.util.ArrayList;
import java.util.List;
/**
 * 类说明:堆栈类
 * 
 * @author 作者: user
 * @version 创建时间:2011-4-5 下午01:17:48
 */
public class SyncStack {
    private List<Character> buffer = new ArrayList<Character>();
    public SyncStack() {
    }
    // 堆栈取数据
    public synchronized char pop() {
        char c;
        if (buffer.size() == 0) {
            try {
                System.out.println(Thread.currentThread().getName()
                        + " 正在等待 ……………………");
                this.wait();// 如果堆栈中没有数据 则线程等待
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
        c = ((Character) buffer.get(buffer.size() - 1)).charValue();
        buffer.remove(buffer.size() - 1);
        return c;
    }
    // 向堆栈中添加数据
    public synchronized void push(char c) {
        this.notify();// 唤醒在此对象监视器上等待的单个线程
        Character ch = new Character(c);
        buffer.add(ch);
    }
}

主方法

/**
 * 类说明:
 * 
 * @author 作者: user
 * @version 创建时间:2011-4-5 下午01:59:54
 */
public class Main {
    /**
     * @param args
     */
    public static void main(String[] args) {
        SyncStack ss = new SyncStack();
        //生产者p
        Producer p = new Producer(ss);
        Thread t1 = new Thread(p);
        t1.start();
        //生产者p2
        Producer p2 = new Producer(ss);
        Thread t3 = new Thread(p2);
        t3.start();
        //消费者1
        Consumer c = new Consumer(ss);
        Thread t2 = new Thread(c);
        t2.setName("消费者1 ");
        t2.start();
        //消费者1
        Consumer c2 = new Consumer(ss);
        Thread t4 = new Thread(c2);
        t4.setName("消费者2 ");
        t4.start();
    }
}
点赞
收藏
评论区
推荐文章
blmius blmius
3年前
MySQL:[Err] 1292 - Incorrect datetime value: ‘0000-00-00 00:00:00‘ for column ‘CREATE_TIME‘ at row 1
文章目录问题用navicat导入数据时,报错:原因这是因为当前的MySQL不支持datetime为0的情况。解决修改sql\mode:sql\mode:SQLMode定义了MySQL应支持的SQL语法、数据校验等,这样可以更容易地在不同的环境中使用MySQL。全局s
皕杰报表之UUID
​在我们用皕杰报表工具设计填报报表时,如何在新增行里自动增加id呢?能新增整数排序id吗?目前可以在新增行里自动增加id,但只能用uuid函数增加UUID编码,不能新增整数排序id。uuid函数说明:获取一个UUID,可以在填报表中用来创建数据ID语法:uuid()或uuid(sep)参数说明:sep布尔值,生成的uuid中是否包含分隔符'',缺省为
待兔 待兔
3个月前
手写Java HashMap源码
HashMap的使用教程HashMap的使用教程HashMap的使用教程HashMap的使用教程HashMap的使用教程22
九章 九章
3年前
一 java线程的等待/通知模型
java中线程之间的通信问题,有这么一个模型:一个线程修改了一个对象的值,而另一个线程感知到了变化,然后进行相应的操作,整个过程开始于一个线程,而最终执行又是另一个线程。前者是生产者,后者就是消费者,也可以叫做生产者消费者问题生产者生产了产品,如何通知消费者?下面就介绍下java线程中的等待通知机制。其它语言类似,自行研究。代码附上下面是以买小
Wesley13 Wesley13
3年前
Java爬虫之JSoup使用教程
title:Java爬虫之JSoup使用教程date:201812248:00:000800update:201812248:00:000800author:mecover:https://imgblog.csdnimg.cn/20181224144920712(https://www.oschin
Wesley13 Wesley13
3年前
Java日期时间API系列31
  时间戳是指格林威治时间1970年01月01日00时00分00秒起至现在的总毫秒数,是所有时间的基础,其他时间可以通过时间戳转换得到。Java中本来已经有相关获取时间戳的方法,Java8后增加新的类Instant等专用于处理时间戳问题。 1获取时间戳的方法和性能对比1.1获取时间戳方法Java8以前
Wesley13 Wesley13
3年前
03.Android崩溃Crash库之ExceptionHandler分析
目录总结00.异常处理几个常用api01.UncaughtExceptionHandler02.Java线程处理异常分析03.Android中线程处理异常分析04.为何使用setDefaultUncaughtExceptionHandler前沿上一篇整体介绍了crash崩溃
Wesley13 Wesley13
3年前
Java日期时间API系列35
  通过Java日期时间API系列1Jdk7及以前的日期时间类(https://www.oschina.net/action/GoToLink?urlhttps%3A%2F%2Fwww.cnblogs.com%2Fxkzhangsanx%2Fp%2F12032719.html)中得知,Java8以前除了java.sql.Timestamp扩充
Wesley13 Wesley13
3年前
00:Java简单了解
浅谈Java之概述Java是SUN(StanfordUniversityNetwork),斯坦福大学网络公司)1995年推出的一门高级编程语言。Java是一种面向Internet的编程语言。随着Java技术在web方面的不断成熟,已经成为Web应用程序的首选开发语言。Java是简单易学,完全面向对象,安全可靠,与平台无关的编程语言。
Python进阶者 Python进阶者
9个月前
Excel中这日期老是出来00:00:00,怎么用Pandas把这个去除
大家好,我是皮皮。一、前言前几天在Python白银交流群【上海新年人】问了一个Pandas数据筛选的问题。问题如下:这日期老是出来00:00:00,怎么把这个去除。二、实现过程后来【论草莓如何成为冻干莓】给了一个思路和代码如下:pd.toexcel之前把这