一生产一消费:操作栈

本实例是使生产者向堆栈List对象中放入数据,使消费者从List堆栈中取出数据。List最大容量是1

package Third;

import java.util.ArrayList;
import java.util.List; public class MyStack {
private List list = new ArrayList(); synchronized public void push() {
try {
if (list.size() == 1) {
this.wait();
}
list.add("anyString=" + Math.random());
this.notify();
System.out.println("push=" + list.size());
} catch (InterruptedException e) {
e.printStackTrace();
}
} synchronized public String pop() {
String returnValue = "";
try {
if (list.size() == 0) {
System.out.println("pop操作中的:"
+ Thread.currentThread().getName() + " 线程呈wait状态");
this.wait();
}
returnValue = "" + list.get(0);
list.remove(0);
this.notify();
System.out.println("pop=" + list.size());
} catch (InterruptedException e) {
e.printStackTrace();
}
return returnValue;
}
}
package Third;

public class P_Thread extends Thread {

    private P p;

    public P_Thread(P p) {
super();
this.p = p;
} @Override
public void run() {
while (true) {
p.pushService();
}
} }
package Third;

public class C_Thread extends Thread {

    private C r;

    public C_Thread(C r) {
super();
this.r = r;
} @Override
public void run() {
while (true) {
r.popService();
}
} }
package Third;

public class P {

    private MyStack myStack;

    public P(MyStack myStack) {
super();
this.myStack = myStack;
} public void pushService() {
myStack.push();
}
}
package Third;

public class C {

    private MyStack myStack;

    public C(MyStack myStack) {
super();
this.myStack = myStack;
} public void popService() {
System.out.println("pop=" + myStack.pop());
}
}
package Third;

public class Run {
public static void main(String[] args) {
MyStack myStack = new MyStack(); P p = new P(myStack);
C r = new C(myStack); P_Thread pThread = new P_Thread(p);
C_Thread rThread = new C_Thread(r);
pThread.start();
rThread.start();
} }

程序运行的结果是size()不会大于1

一生产多消费-操作栈:解决wait条件改变与假死

上述代码只需要更改run.java

package Third;

public class Run {
public static void main(String[] args) throws InterruptedException {
MyStack myStack = new MyStack(); P p = new P(myStack); C r1 = new C(myStack);
C r2 = new C(myStack);
C r3 = new C(myStack);
C r4 = new C(myStack);
C r5 = new C(myStack); P_Thread pThread = new P_Thread(p);
pThread.start(); C_Thread cThread1 = new C_Thread(r1);
C_Thread cThread2 = new C_Thread(r2);
C_Thread cThread3 = new C_Thread(r3);
C_Thread cThread4 = new C_Thread(r4);
C_Thread cThread5 = new C_Thread(r5);
cThread1.start();
cThread2.start();
cThread3.start();
cThread4.start();
cThread5.start();
} }

问题的出现是因为在Mystack.java类中使用了if语句作为条件判断。因为条件发生改变时并没有及时的相应,所以多个呈wait状态的线程被唤醒,继而执行list.remove(0)代码而出现异常。解决这个办法是,将if改成while

package Third;

import java.util.ArrayList;
import java.util.List; public class MyStack {
private List list = new ArrayList(); synchronized public void push() {
try {
while (list.size() == 1) {
this.wait();
}
list.add("anyString=" + Math.random());
this.notify();
System.out.println("push=" + list.size());
} catch (InterruptedException e) {
e.printStackTrace();
}
} synchronized public String pop() {
String returnValue = "";
try {
while (list.size() == 0) {
System.out.println("pop操作中的:"
+ Thread.currentThread().getName() + " 线程呈wait状态");
this.wait();
}
returnValue = "" + list.get(0);
list.remove(0);
this.notify();
System.out.println("pop=" + list.size());
} catch (InterruptedException e) {
e.printStackTrace();
}
return returnValue;
}
}

出现了假死状态,解决办法是notifyAll()

多生产与一消费:操作栈

package Third;

public class Run {
public static void main(String[] args) throws InterruptedException {
MyStack myStack = new MyStack(); P p1 = new P(myStack);
P p2 = new P(myStack);
P p3 = new P(myStack);
P p4 = new P(myStack);
P p5 = new P(myStack);
P p6 = new P(myStack); P_Thread pThread1 = new P_Thread(p1);
P_Thread pThread2 = new P_Thread(p2);
P_Thread pThread3 = new P_Thread(p3);
P_Thread pThread4 = new P_Thread(p4);
P_Thread pThread5 = new P_Thread(p5);
P_Thread pThread6 = new P_Thread(p6);
pThread1.start();
pThread2.start();
pThread3.start();
pThread4.start();
pThread5.start();
pThread6.start(); C c1 = new C(myStack);
C_Thread cThread = new C_Thread(c1);
cThread.start(); } }

多生产与多消费:操作栈

package Third;

public class Run {
public static void main(String[] args) throws InterruptedException {
MyStack myStack = new MyStack(); P p1 = new P(myStack);
P p2 = new P(myStack);
P p3 = new P(myStack);
P p4 = new P(myStack);
P p5 = new P(myStack);
P p6 = new P(myStack); P_Thread pThread1 = new P_Thread(p1);
P_Thread pThread2 = new P_Thread(p2);
P_Thread pThread3 = new P_Thread(p3);
P_Thread pThread4 = new P_Thread(p4);
P_Thread pThread5 = new P_Thread(p5);
P_Thread pThread6 = new P_Thread(p6);
pThread1.start();
pThread2.start();
pThread3.start();
pThread4.start();
pThread5.start();
pThread6.start(); C r1 = new C(myStack);
C r2 = new C(myStack);
C r3 = new C(myStack);
C r4 = new C(myStack);
C r5 = new C(myStack);
C r6 = new C(myStack);
C r7 = new C(myStack);
C r8 = new C(myStack); C_Thread cThread1 = new C_Thread(r1);
C_Thread cThread2 = new C_Thread(r2);
C_Thread cThread3 = new C_Thread(r3);
C_Thread cThread4 = new C_Thread(r4);
C_Thread cThread5 = new C_Thread(r5);
C_Thread cThread6 = new C_Thread(r6);
C_Thread cThread7 = new C_Thread(r7);
C_Thread cThread8 = new C_Thread(r8); cThread1.start();
cThread2.start();
cThread3.start();
cThread4.start();
cThread5.start();
cThread6.start();
cThread7.start();
cThread8.start(); } }

通过管道进行线程间通信:字节流(见书)

通过管道进行线程间通信:字符流(见书)

实战:等待/通知之交叉备份

package Third;

public class DBTools {

    volatile private boolean prevIsA = false;

    synchronized public void backupA() {
try {
while (prevIsA == true) {
wait();
}
for (int i = 0; i < 5; i++) {
System.out.println("★★★★★");
}
prevIsA = true;
notifyAll();
} catch (InterruptedException e) {
e.printStackTrace();
}
} synchronized public void backupB() {
try {
while (prevIsA == false) {
wait();
}
for (int i = 0; i < 5; i++) {
System.out.println("☆☆☆☆☆");
}
prevIsA = false;
notifyAll();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
package Third;

public class BackupA extends Thread {

    private DBTools dbtools;

    public BackupA(DBTools dbtools) {
super();
this.dbtools = dbtools;
} @Override
public void run() {
dbtools.backupA();
} }
package Third;

public class BackupB extends Thread {

    private DBTools dbtools;

    public BackupB(DBTools dbtools) {
super();
this.dbtools = dbtools;
} @Override
public void run() {
dbtools.backupB();
} }
package Third;

public class Run {

    public static void main(String[] args) {
DBTools dbtools = new DBTools();
for (int i = 0; i < 20; i++) {
BackupB output = new BackupB(dbtools);
output.start();
BackupA input = new BackupA(dbtools);
input.start();
}
} }

《Java多线程编程核心技术》读后感(十)的更多相关文章

  1. Java多线程编程核心技术---学习分享

    继承Thread类实现多线程 public class MyThread extends Thread { @Override public void run() { super.run(); Sys ...

  2. Java多线程编程核心技术---对象及变量的并发访问(二)

    数据类型String的常量池特性 在JVM中具有String常量池缓存的功能. public class Service { public static void print(String str){ ...

  3. Java多线程编程核心技术

    Java多线程编程核心技术 这本书有利于对Java多线程API的理解,但不容易从中总结规律. JDK文档 1. Thread类 部分源码: public class Thread implements ...

  4. 《Java多线程编程核心技术》推荐

    写这篇博客主要是给猿友们推荐一本书<Java多线程编程核心技术>. 之所以要推荐它,主要因为这本书写得十分通俗易懂,以实例贯穿整本书,使得原本抽象的概念,理解起来不再抽象. 只要你有一点点 ...

  5. 《java多线程编程核心技术》(一)使用多线程

    了解多线程 进程和多线程的概念和线程的优点: 提及多线程技术,不得不提及"进程"这个概念.百度百科对"进程"的解释如下: 进程(Process)是计算机中的程序 ...

  6. 《Java 多线程编程核心技术》- 笔记

    作为业务开发人员,能够在工作中用到的技术其实不多.虽然平时老是说什么,多线程,并发,注入,攻击!但是在实际工作中,这些东西不见得用得上.因为,我们用的框架已经把这些事做掉了. 比如web开发,外面有大 ...

  7. Thread.currentThread()和this的区别——《Java多线程编程核心技术》

    前言:在阅读<Java多线程编程核心技术>过程中,对书中程序代码Thread.currentThread()与this的区别有点混淆,这里记录下来,加深印象与理解. 具体代码如下: pub ...

  8. Java多线程编程核心技术(三)多线程通信

    线程是操作系统中独立的个体,但这些个体如果不经过特殊的处理就不能成为一个整体.线程间的通信就是成为整体的必用方案之一,可以说,使线程间进行通信后,系统之间的交互性会更强大,在大大提高CPU利用率的同时 ...

  9. Java多线程编程核心技术(二)对象及变量的并发访问

    本文主要介绍Java多线程中的同步,也就是如何在Java语言中写出线程安全的程序,如何在Java语言中解决非线程安全的相关问题.阅读本文应该着重掌握如下技术点: synchronized对象监视器为O ...

  10. Java多线程编程核心技术(一)Java多线程技能

    1.进程和线程 一个程序就是一个进程,而一个程序中的多个任务则被称为线程. 进程是表示资源分配的基本单位,线程是进程中执行运算的最小单位,亦是调度运行的基本单位. 举个例子: 打开你的计算机上的任务管 ...

随机推荐

  1. EntityFramework走马观花之CRUD(中)

    如果是独立的实体对象,在底层数据库中它对应一张独立的表,那么,对它进行新建.删除和修改没有任何难度,实在不值浪费笔墨在它上头. 在现实项目中,完全独立的对象少之又少,绝大多数情况都是对象之间有着紧密的 ...

  2. iOS block-base 动画简单用法+关键帧动画设置线性变化速度的问题

    本文转载至 http://www.tuicool.com/articles/aANBF3m 时间 2014-12-07 20:13:37  segmentfault-博客原文  http://segm ...

  3. 九度OJ 1033:继续xxx定律 (基础题)

    时间限制:1 秒 内存限制:32 兆 特殊判题:否 提交:4987 解决:1201 题目描述:     当n为3时,我们在验证xxx定律的过程中会得到一个序列,3,5,8,4,2,1,将3称为关键数, ...

  4. Cauchy sequence Hilbert space 希尔波特空间的柯西序列

    http://mathworld.wolfram.com/HilbertSpace.html A Hilbert space is a vector space  with an inner prod ...

  5. 【题解】[P3557 POI2013]GRA-Tower Defense Game

    [题解][P3557 POI2013]GRA-Tower Defense Game 这道题是真的** 根据题目给的\(k\),可以知道,我们随便放塔,只要不全放一起,一定是一种合法的方案. 直接枚举就 ...

  6. ORACLE DATABASE 10g EXPRESS EDITION LICENSE AGREEMENT

     启动Tomcat之后出现全是英文错误: ORACLE DATABASE 10g EXPRESS EDITION LICENSE AGREEMENT To use this license, yo ...

  7. org.apache.catalina.Lifecycle

    org.apache.catalina.Lifecycle start() *  ----------------------------- *  |                         ...

  8. CentOS下配置静态IP

    第一.在VMware中进行配置使用桥接的方式.点击编辑选择虚拟网络编辑器 选择桥接模式,选择桥接到外部的网卡.选择我们主机下的网卡 第二步.配置虚拟机使用桥接模式 第三步:启动虚拟机进入到 /etc/ ...

  9. 服务器安装tensorflow导入模块报错Illegal instruction (core dumped)

    在ubuntu上安装tensorflow后导入模块显示Illegal instruction (core dumped) 服务器的版本是Ubuntu 16.04.5 降低版本,成功导入模块 pip3 ...

  10. 【Leetcode-easy】Remove Duplicates from Sorted Array

    题目要求:删除排好序的含有重复元素的数组.返回去除重复后的数组长度,并更新原始数组.不能使用额外空间. 思路:要不额外的使用内存空间,那么只有遍历数组,count保持下一个不重复的数字,遍历过程中如果 ...