《Java多线程编程核心技术》读后感(八)
不使用等待/通知机制实现线程间通信
使用sleep()结合while(true)死循环来实现多个线程间通信
package Third; import java.util.ArrayList;
import java.util.List; public class MyList { private List list = new ArrayList(); public void add() {
list.add("高洪岩");
} public int size() {
return list.size();
} }
package Third;
public class ThreadA extends Thread {
private MyList list;
public ThreadA(MyList list) {
super();
this.list = list;
}
@Override
public void run() {
try {
for (int i = 0; i < 10; i++) {
list.add();
System.out.println("添加了" + (i + 1) + "个元素");
Thread.sleep(1000);
}
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
package Third;
public class ThreadB extends Thread {
private MyList list;
public ThreadB(MyList list) {
super();
this.list = list;
}
@Override
public void run() {
try {
while (true) {
if (list.size() == 5) {
System.out.println("==5了,线程b要退出了!");
throw new InterruptedException();
}
}
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
package Third;
public class Test {
public static void main(String[] args) {
MyList service = new MyList();
ThreadA a = new ThreadA(service);
a.setName("A");
a.start();
ThreadB b = new ThreadB(service);
b.setName("B");
b.start();
}
}

虽然两个线程实现了通信,但有一个弊端是,线程ThreadB.java不停地通过while语轮询机制来检测某一个条件,这样会浪费CPU资源。
如果轮询的时间间隔小,更浪费cpu资源;如果轮询时间间隔大,有可能会娶不到想要的数据。所以就需要有一种机制来减少CPU的资源浪费,而且还可以实现在多个线程间通信,它就是“”wait/notify“”机制。
什么是等待/通信机制
等待/通知机制的实现



package Third;
public class Test1 {
public static void main(String[] args) {
try {
String newString = new String("");
newString.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}

出现异常的原因是没有“”对象监视器“”,也就是没有同步加锁
package Third;
public class Test2 {
public static void main(String[] args) {
try {
String lock = new String();
System.out.println("syn上面");
synchronized (lock) {
System.out.println("syn第一行");
lock.wait();
System.out.println("wait下的代码!");
}
System.out.println("syn下面的代码");
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}

线程不能永远等待下去,那样程序就停止不前,不继续向下运行了。如何使呈现wait状态的线程继续运行?答案是notify()
package Third;
public class MyThread1 extends Thread {
private Object lock;
public MyThread1(Object lock) {
super();
this.lock = lock;
}
@Override
public void run() {
try {
synchronized (lock) {
System.out.println("开始 wait time=" + System.currentTimeMillis());
lock.wait();
System.out.println("结束 wait time=" + System.currentTimeMillis());
}
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
package Third;
public class MyThread2 extends Thread {
private Object lock;
public MyThread2(Object lock) {
super();
this.lock = lock;
}
@Override
public void run() {
synchronized (lock) {
System.out.println("开始notify time=" + System.currentTimeMillis());
lock.notify();
System.out.println("结束notify time=" + System.currentTimeMillis());
}
}
}
package Third;
public class MyThread2 extends Thread {
private Object lock;
public MyThread2(Object lock) {
super();
this.lock = lock;
}
@Override
public void run() {
synchronized (lock) {
System.out.println("开始notify time=" + System.currentTimeMillis());
lock.notify();
System.out.println("结束notify time=" + System.currentTimeMillis());
}
}
}

下面实现前面的size()=5的实验
package Third; import java.util.ArrayList;
import java.util.List; public class MyList { private static List list = new ArrayList(); public static void add() {
list.add("anyString");
} public static int size() {
return list.size();
} }
package Third;
public class ThreadA extends Thread {
private Object lock;
public ThreadA(Object lock) {
super();
this.lock = lock;
}
@Override
public void run() {
try {
synchronized (lock) {
if (MyList.size() != 5) {
System.out.println("wait begin "
+ System.currentTimeMillis());
lock.wait();
System.out.println("wait end "
+ System.currentTimeMillis());
}
}
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
package Third;
public class ThreadB extends Thread {
private Object lock;
public ThreadB(Object lock) {
super();
this.lock = lock;
}
@Override
public void run() {
try {
synchronized (lock) {
for (int i = 0; i < 10; i++) {
MyList.add();
if (MyList.size() == 5) {
lock.notify();
System.out.println("已发出通知!");
}
System.out.println("添加了" + (i + 1) + "个元素!");
Thread.sleep(1000);
}
}
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
package Third;
public class Run {
public static void main(String[] args) {
try {
Object lock = new Object();
ThreadA a = new ThreadA(lock);
a.start();
Thread.sleep(50);
ThreadB b = new ThreadB(lock);
b.start();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}

日志信息wait end在最后输出,这也说明notify()执行后并不立即释放锁






方法wait()锁释放与notify()锁不释放
当方法wait()被执行后,锁被自动释放,但执行完notify()方法,锁却不自动释放
package Third;
public class Service {
public void testMethod(Object lock) {
try {
synchronized (lock) {
System.out.println("begin wait()");
lock.wait();
System.out.println(" end wait()");
}
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
package Third;
public class ThreadA extends Thread {
private Object lock;
public ThreadA(Object lock) {
super();
this.lock = lock;
}
@Override
public void run() {
Service service = new Service();
service.testMethod(lock);
}
}
package Third;
public class ThreadB extends Thread {
private Object lock;
public ThreadB(Object lock) {
super();
this.lock = lock;
}
@Override
public void run() {
Service service = new Service();
service.testMethod(lock);
}
}
package Third;
public class Test {
public static void main(String[] args) {
Object lock = new Object();
ThreadA a = new ThreadA(lock);
a.start();
ThreadB b = new ThreadB(lock);
b.start();
}
}

下面验证方法notify()被执行后,不释放锁
package Third;
public class Service {
public void testMethod(Object lock) {
try {
synchronized (lock) {
System.out.println("begin wait() ThreadName="
+ Thread.currentThread().getName());
lock.wait();
System.out.println(" end wait() ThreadName="
+ Thread.currentThread().getName());
}
} catch (InterruptedException e) {
e.printStackTrace();
}
}
public void synNotifyMethod(Object lock) {
try {
synchronized (lock) {
System.out.println("begin notify() ThreadName="
+ Thread.currentThread().getName() + " time="
+ System.currentTimeMillis());
lock.notify();
Thread.sleep(5000);
System.out.println(" end notify() ThreadName="
+ Thread.currentThread().getName() + " time="
+ System.currentTimeMillis());
}
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
package Third;
public class ThreadA extends Thread {
private Object lock;
public ThreadA(Object lock) {
super();
this.lock = lock;
}
@Override
public void run() {
Service service = new Service();
service.testMethod(lock);
}
}
package Third;
public class NotifyThread extends Thread {
private Object lock;
public NotifyThread(Object lock) {
super();
this.lock = lock;
}
@Override
public void run() {
Service service = new Service();
service.synNotifyMethod(lock);
}
}
package Third;
public class synNotifyMethodThread extends Thread {
private Object lock;
public synNotifyMethodThread(Object lock) {
super();
this.lock = lock;
}
@Override
public void run() {
Service service = new Service();
service.synNotifyMethod(lock);
}
}
package Third;
public class Test {
public static void main(String[] args) throws InterruptedException {
Object lock = new Object();
ThreadA a = new ThreadA(lock);
a.start();
NotifyThread notifyThread = new NotifyThread(lock);
notifyThread.start();
synNotifyMethodThread c = new synNotifyMethodThread(lock);
c.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.进程和线程 一个程序就是一个进程,而一个程序中的多个任务则被称为线程. 进程是表示资源分配的基本单位,线程是进程中执行运算的最小单位,亦是调度运行的基本单位. 举个例子: 打开你的计算机上的任务管 ...
随机推荐
- 点击textbox弹出对话框,返回弹出对话框的值
主要是在父页面使用 function PopupWindow() { window.open(url, "", "status=no,resizab ...
- 整合Settings.bundle显示版本信息
本文转载至 http://www.cocoachina.com/ios/20141103/10112.html iOS开发XCode版本管理Debug开发Tips 现在你有一个App,你同事的iP ...
- [转]JS学习之正则表达式
js正则表达式实例 正则表达式可以: •测试字符串的某个模式.例如,可以对一个输入字符串进行测试,看在该字符串是否存在一个电话号码模式或一个信用卡号码模式.这称为数据有效性验证 •替换文本.可以在文档 ...
- 关于eclipse 插件的挂载
学习java的时候,不喜欢myeclipse 这种插件,什么都准备好了,自己动手就少了,不利于自己学习,现在我就diy 自己选几个插件来用,基本上就是 eclipse 加上我自己要用的插件,插件的安装 ...
- google guice
1 google guice是什么 google guice是一个轻量的DI容器. 2 guice和spring对比 spring的配置放在xm文件中,guice的配置放在Module中. guice ...
- Method invoke 方法
这个问题要看明白源码才能解决
- 原生js基础学习--正则RegExp
转义字符"\" 使用反斜杠之后,会强制的将"\"之后的字符取消掉原来的意思转换成文本, 转义符号不会输出 var str= "abc\"de ...
- 使用urllib2打开网页的三种方法(Python2)
python2才有urllib2模块,python3把urllib和urllib2封装成了urllib模块 使用urllib2打开网页的三种方法 #coding:utf-8 import urllib ...
- client , offset , scroll 系列 及百度导航栏案例
1. client 系列 示例 : <!DOCTYPE html> <html> <head> <meta charset="UTF-8" ...
- <再看TCP/IP第一卷>关于链路层的知识细节及相关协议
在TCP/IP协议族中,链路层的主要有三个目的: (1)为IP模块发送和接受数据报 (2)为ARP模块发送ARP请求和接受ARP应答 (3)为RARP发送RARP请求和接受RARP应答 TCP/IP支 ...