《Java多线程编程核心技术》读后感(十)
一生产一消费:操作栈
本实例是使生产者向堆栈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多线程编程核心技术》读后感(十)的更多相关文章
- Java多线程编程核心技术---学习分享
继承Thread类实现多线程 public class MyThread extends Thread { @Override public void run() { super.run(); Sys ...
- Java多线程编程核心技术---对象及变量的并发访问(二)
数据类型String的常量池特性 在JVM中具有String常量池缓存的功能. public class Service { public static void print(String str){ ...
- Java多线程编程核心技术
Java多线程编程核心技术 这本书有利于对Java多线程API的理解,但不容易从中总结规律. JDK文档 1. Thread类 部分源码: public class Thread implements ...
- 《Java多线程编程核心技术》推荐
写这篇博客主要是给猿友们推荐一本书<Java多线程编程核心技术>. 之所以要推荐它,主要因为这本书写得十分通俗易懂,以实例贯穿整本书,使得原本抽象的概念,理解起来不再抽象. 只要你有一点点 ...
- 《java多线程编程核心技术》(一)使用多线程
了解多线程 进程和多线程的概念和线程的优点: 提及多线程技术,不得不提及"进程"这个概念.百度百科对"进程"的解释如下: 进程(Process)是计算机中的程序 ...
- 《Java 多线程编程核心技术》- 笔记
作为业务开发人员,能够在工作中用到的技术其实不多.虽然平时老是说什么,多线程,并发,注入,攻击!但是在实际工作中,这些东西不见得用得上.因为,我们用的框架已经把这些事做掉了. 比如web开发,外面有大 ...
- Thread.currentThread()和this的区别——《Java多线程编程核心技术》
前言:在阅读<Java多线程编程核心技术>过程中,对书中程序代码Thread.currentThread()与this的区别有点混淆,这里记录下来,加深印象与理解. 具体代码如下: pub ...
- Java多线程编程核心技术(三)多线程通信
线程是操作系统中独立的个体,但这些个体如果不经过特殊的处理就不能成为一个整体.线程间的通信就是成为整体的必用方案之一,可以说,使线程间进行通信后,系统之间的交互性会更强大,在大大提高CPU利用率的同时 ...
- Java多线程编程核心技术(二)对象及变量的并发访问
本文主要介绍Java多线程中的同步,也就是如何在Java语言中写出线程安全的程序,如何在Java语言中解决非线程安全的相关问题.阅读本文应该着重掌握如下技术点: synchronized对象监视器为O ...
- Java多线程编程核心技术(一)Java多线程技能
1.进程和线程 一个程序就是一个进程,而一个程序中的多个任务则被称为线程. 进程是表示资源分配的基本单位,线程是进程中执行运算的最小单位,亦是调度运行的基本单位. 举个例子: 打开你的计算机上的任务管 ...
随机推荐
- DB2 时间操作
1. SQL语句得到当前的日期,时间和时间戳 SELECT current date FROM sysibm.sysdummy1; SELECT current time FROM s ...
- JS实现图片无缝滚动特效;附addEventListener()方法、offsetLeft和offsetWidth属性。
一:html部分 <body> <input id="btn1" type="button" value="向左"> ...
- 【BZOJ2245】[SDOI2011]工作安排 拆边费用流
[BZOJ2245][SDOI2011]工作安排 Description 你的公司接到了一批订单.订单要求你的公司提供n类产品,产品被编号为1~n,其中第i类产品共需要Ci件.公司共有m名员工,员工被 ...
- 【BZOJ1786】[Ahoi2008]Pair 配对 DP
[BZOJ1786][Ahoi2008]Pair 配对 Description Input Output Sample Input 5 4 4 2 -1 -1 3 Sample Output 4 题解 ...
- 硬分叉后,BCH的钱包解决方案
上周BCH进行了硬分叉,分叉成了两条链:BCH和BCHSV,对于分叉后的BCH如何进行交易呢?钱包是否有相关的危险因素? 由于分叉后的两条链没做重放保护,可能导致一条链上发起的交易,在另一条链上做重放 ...
- Java for LeetCode 117 Populating Next Right Pointers in Each Node II
Follow up for problem "Populating Next Right Pointers in Each Node". What if the given tre ...
- ubuntu nohup命令用法
让程序在后台运行 该命令的一般形式nohup command & 程序在后台运行并打印日志 nohup ./china_fund.py > china_fund.file 2>&a ...
- CLion提示can't find stdio.h等错误
先上解决办法,启动参数如下: $ LANG=en_US.UTF-8 /path/to/clion.sh 查了好知久,竟然就由于编码的原因.可是Ubuntu已经设置为英文UTF-8,还是可以通过上面的方 ...
- 《C prime plus (第五版)》 ---第11章 字符串和字符串函数---4
字符串的例子: 1.字符串排序: 应用范围:准备花名册,建立索引以及很多情况下都会用刀字符串的排序.这个程序的主要工具就是strcmp(). 算法:读一个字符串数组,对它们进行排序并输出. #incl ...
- hadoop —— teragen & terasort
这两个类所在目录: hadoop-examples-0.20.2-cdh3u6.jar 中: 代码: TeraGen.java: /** * Licensed to the Apache Softwa ...