经典多线程实例:生产者消费者问题
来源:互联网 发布:剑雨江湖宠物进阶数据 编辑:程序博客网 时间:2024/05/20 21:22
大部分人在理解Java的多线程这个问题有点困难,尤其是一些刚开始接触的编程语言是C语言的人。考虑到用C语言的人接触的都是一个主线程,下面给出的例子并没有太复杂的结构。主要是用来理解多线程的机制。
采用的例子:生产者消费者问题。
SyncStack存储WoTou
Producer生产WoTou
Consumer消费WoTou
package com.example.thread;public class ProducerConsumer {public static void main(String[] args) {SyncStack ss = new SyncStack();Producer p = new Producer(ss);Consumer c = new Consumer(ss);new Thread(p).start();new Thread(c).start();}}class WoTou {int id;public WoTou(int id) {super();this.id = id;}@Overridepublic String toString() {return "WoTou [id=" + id + "]";}}class SyncStack {int index = 0;WoTou[] arrWT = new WoTou[6];public synchronized void push(WoTou wt) {while(index == arrWT.length) {try {this.wait();} catch (InterruptedException e) {e.printStackTrace();}}this.notify();arrWT[index] = wt;index++;}public synchronized WoTou pop() {while(index == 0) {try {this.wait();} catch (InterruptedException e) {e.printStackTrace();}}this.notify();index--;return arrWT[index];}}class Producer implements Runnable {SyncStack ss = null;public Producer(SyncStack ss) {super();this.ss = ss;}@Overridepublic void run() {for(int i=0; i<20; i++) {WoTou wt = new WoTou(i);ss.push(wt);System.out.println("生产:" + wt);}}}class Consumer implements Runnable {SyncStack ss = null;public Consumer(SyncStack ss) {super();this.ss = ss;}@Overridepublic void run() {for(int i=0; i<20; i++) {WoTou wt = ss.pop();System.out.println("消费:" + wt);}}}/* wait(),notify(),notifyAll()方法来自java.lang.Objectwait()public final void wait() throws InterruptedException在其他线程调用此对象的 notify() 方法或 notifyAll() 方法前,导致当前线程等待。换句话说,此方法的行为就好像它仅执行 wait(0) 调用一样。 当前线程必须拥有此对象监视器。该线程发布对此监视器的所有权并等待,直到其他线程通过调用 notify 方法,或 notifyAll 方法通知在此对象的监视器上等待的线程醒来。然后该线程将等到重新获得对监视器的所有权后才能继续执行。 对于某一个参数的版本,实现中断和虚假唤醒是可能的,而且此方法应始终在循环中使用: synchronized (obj) {while (<condition does not hold>)obj.wait();... // Perform action appropriate to condition } 此方法只应由作为此对象监视器的所有者的线程来调用。有关线程能够成为监视器所有者的方法的描述,请参阅 notify 方法。 抛出: IllegalMonitorStateException - 如果当前线程不是此对象监视器的所有者。 InterruptedException - 如果在当前线程等待通知之前或者正在等待通知时,任何线程中断了当前线程。在抛出此异常时,当前线程的中断状态 被清除。另请参见:notify(), notifyAll()notifypublic final void notify()唤醒在此对象监视器上等待的单个线程。如果所有线程都在此对象上等待,则会选择唤醒其中一个线程。选择是任意性的,并在对实现做出决定时发生。线程通过调用其中一个 wait 方法,在对象的监视器上等待。 直到当前线程放弃此对象上的锁定,才能继续执行被唤醒的线程。被唤醒的线程将以常规方式与在该对象上主动同步的其他所有线程进行竞争;例如,唤醒的线程在作为锁定此对象的下一个线程方面没有可靠的特权或劣势。 此方法只应由作为此对象监视器的所有者的线程来调用。通过以下三种方法之一,线程可以成为此对象监视器的所有者: 通过执行此对象的同步实例方法。 通过执行在此对象上进行同步的 synchronized 语句的正文。 对于 Class 类型的对象,可以通过执行该类的同步静态方法。 一次只能有一个线程拥有对象的监视器。 抛出: IllegalMonitorStateException - 如果当前线程不是此对象监视器的所有者。另请参见:notifyAll(), wait()notifyAllpublic final void notifyAll()唤醒在此对象监视器上等待的所有线程。线程通过调用其中一个 wait 方法,在对象的监视器上等待。 直到当前线程放弃此对象上的锁定,才能继续执行被唤醒的线程。被唤醒的线程将以常规方式与在该对象上主动同步的其他所有线程进行竞争;例如,唤醒的线程在作为锁定此对象的下一个线程方面没有可靠的特权或劣势。 此方法只应由作为此对象监视器的所有者的线程来调用。有关线程能够成为监视器所有者的方法的描述,请参阅 notify 方法。 抛出: IllegalMonitorStateException - 如果当前线程不是此对象监视器的所有者。另请参见:notify(), wait()*/
运行结果我这不给出,大家可以运行下。加深一下理解。
注:while(index == 0),while(index == arrWT.length)两条语句不可以用if(index == 0),if(index == arrWT.length)
原因是如果在wait方法被打断的时候,不再检查临界值,用while循环可以一直很好的控制边界问题。
在编程以及写项目的时候特别需要注意这两个关键字的区别。
由于本人的水平有限,很多问题并没有给出太多的解释,如果你有任何疑问,希望你可以留言告诉我。
- 经典多线程实例:生产者消费者问题
- 经典多线程Java实例 生产者与消费者
- 多线程经典实例;生产者和消费者
- 多线程经典的 生产者-消费者 实例
- 多线程八 生产者消费者经典问题
- java多线程之生产者消费者经典问题
- 多线程经典问题-生产者与消费者
- 多线程之经典生产者消费者问题
- java多线程之生产者消费者经典问题
- 多线程第八篇 生产者消费者经典问题
- 多线程八 生产者消费者经典问题
- java多线程之生产者消费者经典问题
- java多线程之生产者消费者经典问题
- java多线程之生产者消费者经典问题
- java多线程之生产者消费者经典问题
- java多线程-生产者消费者经典问题
- java多线程经典的生产者消费者问题
- Java经典多线程问题--生产者与消费者
- iphone的单态(singleton)设计模式(即全局单实例模式)
- Linux 下摄像头驱动支持情况(arm linux 同样适用)
- 黑马程序员—asp.net基础篇2
- makefile里PHONY的相关介绍
- Ajax 之一 XMLHttpRequest
- 经典多线程实例:生产者消费者问题
- linux2.6内核下驱动模块的编译方法
- Using System.Configuration.ConfigurationManager Example (VB.NET)
- 编写一个小程序,从标准输入读入一系列string对象,寻找连续重复出现的单词。程序应该找出满足一下条件的单词:该单词的后面紧接着再次出现自己本身。跟踪重复次数最多的单词及其重复次数,输出.
- 用PHP将CMYK格式的JPG文件转为RGB格式
- 安装虚拟机时遇到错误: The unattend file contains an invalid product key
- 如何获取图片的RGB565像素信息
- V4L2驱动详解 API翻译
- cairo教程三