当interrupt方法遇到wait方法

当线程呈wait()状态时,调用线程对象的interrupt()会出现InterruptedException异常

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();
System.out.println("出现异常了,因为呈wait状态的线程被interrupt了!");
}
} }
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 Test {

    public static void main(String[] args) {

        try {
Object lock = new Object(); ThreadA a = new ThreadA(lock);
a.start(); Thread.sleep(5000); a.interrupt();
} catch (InterruptedException e) {
e.printStackTrace();
} } }

只通知一个线程

调用方法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();
}
} }
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 ThreadC extends Thread {
private Object lock; public ThreadC(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() {
synchronized (lock) {
lock.notify(); }
} }
package Third;

public class Test {

    public static void main(String[] args) throws InterruptedException {

        Object lock = new Object();

        ThreadA a = new ThreadA(lock);
a.start(); ThreadB b = new ThreadB(lock);
b.start(); ThreadC c = new ThreadC(lock);
c.start(); Thread.sleep(1000); NotifyThread notifyThread = new NotifyThread(lock);
notifyThread.start(); } }

唤醒所有线程

package Third;

public class NotifyThread extends Thread {
private Object lock; public NotifyThread(Object lock) {
super();
this.lock = lock;
} @Override
public void run() {
synchronized (lock) {
lock.notifyAll(); }
} }

wait(long)的使用

功能是等待某一时间内是否有线程对锁进行唤醒,如果超过这个时间则自动唤醒

当然也可以由其他线程进行唤醒

package Third;

public class MyRunnable {
static private Object lock = new Object();
static private Runnable runnable1 = new Runnable() {
@Override
public void run() {
try {
synchronized (lock) {
System.out.println("wait begin timer="
+ System.currentTimeMillis());
lock.wait(5000);
System.out.println("wait end timer="
+ System.currentTimeMillis());
}
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}; static private Runnable runnable2 = new Runnable() {
@Override
public void run() {
synchronized (lock) {
System.out.println("notify begin timer="
+ System.currentTimeMillis());
lock.notify();
System.out.println("notify end timer="
+ System.currentTimeMillis());
}
}
}; public static void main(String[] args) throws InterruptedException {
Thread t1 = new Thread(runnable1);
t1.start();
Thread.sleep(3000);
Thread t2 = new Thread(runnable2);
t2.start();
} }

通知过早

package Third;

public class MyRun {

    private String lock = new String("");

    private Runnable runnableA = new Runnable() {
@Override
public void run() {
try {
synchronized (lock) { System.out.println("begin wait");
lock.wait();
System.out.println("end wait"); }
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}; private Runnable runnableB = new Runnable() {
@Override
public void run() {
synchronized (lock) {
System.out.println("begin notify");
lock.notify();
System.out.println("end notify"); }
}
}; public static void main(String[] args) throws InterruptedException { MyRun run = new MyRun(); Thread a = new Thread(run.runnableA);
a.start(); Thread b = new Thread(run.runnableB);
b.start(); } }

package Third;

public class MyRun {

    private String lock = new String("");

    private Runnable runnableA = new Runnable() {
@Override
public void run() {
try {
synchronized (lock) { System.out.println("begin wait");
lock.wait();
System.out.println("end wait"); }
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}; private Runnable runnableB = new Runnable() {
@Override
public void run() {
synchronized (lock) {
System.out.println("begin notify");
lock.notify();
System.out.println("end notify"); }
}
}; public static void main(String[] args) throws InterruptedException { MyRun run = new MyRun(); Thread a = new Thread(run.runnableA);
a.start(); Thread.sleep(100); Thread b = new Thread(run.runnableB);
b.start(); } }

如果先通知了,则wait方法也就没有必要执行了

package Third;

public class MyRun {

    private String lock = new String("");
private boolean isFirstRunB = false; private Runnable runnableA = new Runnable() {
@Override
public void run() {
try {
synchronized (lock) {
while (isFirstRunB == false) {
System.out.println("begin wait");
lock.wait();
System.out.println("end wait");
}
}
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}; private Runnable runnableB = new Runnable() {
@Override
public void run() {
synchronized (lock) {
System.out.println("begin notify");
lock.notify();
System.out.println("end notify");
isFirstRunB = true; }
}
}; public static void main(String[] args) throws InterruptedException { MyRun run = new MyRun();
Thread b = new Thread(run.runnableB);
b.start();
Thread.sleep(100);
Thread a = new Thread(run.runnableA);
a.start(); } }

等待wait条件发生变化

在使用wait/notify模式时,还需要注意另外一种情况。也就是wait等待的条件发生了变化,也容易造成程序逻辑混乱

package Third;

public class Add {

    private String lock;

    public Add(String lock) {
super();
this.lock = lock;
} public void add() {
synchronized (lock) {
ValueObject.list.add("anyString");
lock.notifyAll();
}
} }
package Third;

public class Subtract {

    private String lock;

    public Subtract(String lock) {
super();
this.lock = lock;
} public void subtract() {
try {
synchronized (lock) {
if (ValueObject.list.size() == 0) {
System.out.println("wait begin ThreadName="
+ Thread.currentThread().getName());
lock.wait();
System.out.println("wait end ThreadName="
+ Thread.currentThread().getName());
}
ValueObject.list.remove(0);
System.out.println("list size=" + ValueObject.list.size());
}
} catch (InterruptedException e) {
e.printStackTrace();
}
} }
package Third;

import java.util.ArrayList;
import java.util.List; public class ValueObject { public static List list = new ArrayList(); }
package Third;

public class ThreadAdd extends Thread {

    private Add p;

    public ThreadAdd(Add p) {
super();
this.p = p;
} @Override
public void run() {
p.add();
} }
package Third;

public class ThreadSubtract extends Thread {

    private Subtract r;

    public ThreadSubtract(Subtract r) {
super();
this.r = r;
} @Override
public void run() {
r.subtract();
} }
package Third;

public class Run {

    public static void main(String[] args) throws InterruptedException {

        String lock = new String("");

        Add add = new Add(lock);
Subtract subtract = new Subtract(lock); ThreadSubtract subtract1Thread = new ThreadSubtract(subtract);
subtract1Thread.setName("subtract1Thread");
subtract1Thread.start(); ThreadSubtract subtract2Thread = new ThreadSubtract(subtract);
subtract2Thread.setName("subtract2Thread");
subtract2Thread.start(); Thread.sleep(1000); ThreadAdd addThread = new ThreadAdd(add);
addThread.setName("addThread");
addThread.start(); } }

package Third;

public class Subtract {

    private String lock;

    public Subtract(String lock) {
super();
this.lock = lock;
} public void subtract() {
try {
synchronized (lock) {
while (ValueObject.list.size() == 0) {
System.out.println("wait begin ThreadName="
+ Thread.currentThread().getName());
lock.wait();
System.out.println("wait end ThreadName="
+ Thread.currentThread().getName());
}
ValueObject.list.remove(0);
System.out.println("list size=" + ValueObject.list.size());
}
} catch (InterruptedException e) {
e.printStackTrace();
}
} }

生产者/消费者模式实现

1、一生产与一消费:操作值

package Third;

//生产者
public class P { private String lock; public P(String lock) {
super();
this.lock = lock;
} public void setValue() {
try {
synchronized (lock) {
if (!ValueObject.value.equals("")) {
lock.wait();
}
String value = System.currentTimeMillis() + "_"
+ System.nanoTime();
System.out.println("set的值是" + value);
ValueObject.value = value;
lock.notify();
} } catch (InterruptedException e) {
e.printStackTrace();
}
} }
package Third;

//消费者
public class C { private String lock; public C(String lock) {
super();
this.lock = lock;
} public void getValue() {
try {
synchronized (lock) {
if (ValueObject.value.equals("")) {
lock.wait();
}
System.out.println("get的值是" + ValueObject.value);
ValueObject.value = "";
lock.notify();
} } catch (InterruptedException e) {
e.printStackTrace();
}
} }
package Third;

public class ValueObject {

    public static String value = "";

}
package Third;

public class ThreadP extends Thread {

    private P p;

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

public class ThreadC extends Thread {

    private C r;

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

public class Run {

    public static void main(String[] args) {

        String lock = new String("");
P p = new P(lock);
C r = new C(lock); ThreadP pThread = new ThreadP(p);
ThreadC rThread = new ThreadC(r); pThread.start();
rThread.start();
} }

在控制台中打印的日志get和set是交替运行的

2、多生产与多消费:操作值-假死

“”假死“”的现象其实就是线程进入waiting等待状态,如果全部线程都进入waiting状态,则程序就不再执行任何业务功能了,整个项目呈停止状态

package Third;

//消费者
public class C { private String lock; public C(String lock) {
super();
this.lock = lock;
} public void getValue() {
try {
synchronized (lock) {
while (ValueObject.value.equals("")) {
System.out.println("消费者 "
+ Thread.currentThread().getName() + " WAITING了☆");
lock.wait();
}
System.out.println("消费者 " + Thread.currentThread().getName()
+ " RUNNABLE了");
ValueObject.value = "";
lock.notify();
} } catch (InterruptedException e) {
e.printStackTrace();
}
} }
package Third;

//生产者
public class P { private String lock; public P(String lock) {
super();
this.lock = lock;
} public void setValue() {
try {
synchronized (lock) {
while (!ValueObject.value.equals("")) {
System.out.println("生产者 "
+ Thread.currentThread().getName() + " WAITING了★");
lock.wait();
}
System.out.println("生产者 " + Thread.currentThread().getName()
+ " RUNNABLE了");
String value = System.currentTimeMillis() + "_"
+ System.nanoTime();
ValueObject.value = value;
lock.notify();
} } catch (InterruptedException e) {
e.printStackTrace();
}
} }
package Third;

public class ValueObject {

    public static String value = "";

}
package Third;

public class ThreadP extends Thread {

    private P p;

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

public class ThreadC extends Thread {

    private C r;

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

public class Run {

    public static void main(String[] args) throws InterruptedException {

        String lock = new String("");
P p = new P(lock);
C r = new C(lock); ThreadP[] pThread = new ThreadP[2];
ThreadC[] rThread = new ThreadC[2]; for (int i = 0; i < 2; i++) {
pThread[i] = new ThreadP(p);
pThread[i].setName("生产者" + (i + 1)); rThread[i] = new ThreadC(r);
rThread[i].setName("消费者" + (i + 1)); pThread[i].start();
rThread[i].start();
} Thread.sleep(5000);
Thread[] threadArray = new Thread[Thread.currentThread()
.getThreadGroup().activeCount()];
Thread.currentThread().getThreadGroup().enumerate(threadArray); for (int i = 0; i < threadArray.length; i++) {
System.out.println(threadArray[i].getName() + " "
+ threadArray[i].getState());
}
} }

假死出现的主要原因是有可能连续唤醒同类

多生产与多消费:操作值

将上面项目的P.java和C.java文件中的notify()改成notifyAll()即可,不光通知同类线程,也包括异类

《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. 【百度之星复赛】T5 Valley Numer

    Valley Numer Problem Description 众所周知,度度熊非常喜欢数字. 它最近发明了一种新的数字:Valley Number,像山谷一样的数字. 当一个数字,从左到右依次看过 ...

  2. sqlite与sqlserver区别

    1.查询时把两个字段拼接在一起 --sqlserver-- select Filed1+'@'+Filed2 from table --sqlite-- select Filed1||'@'||Fil ...

  3. Linux内核的编译安装

    前言 Linux内核是Linux操作2347系统的核心,也是整个Linux功能体现的核心,就如同发动机在汽车中的重要性.内核主要功能包括进程管理.内存管理.文件管理.设备管理.网络管理等.Linux内 ...

  4. iOS 10 权限配置大全

    <!-- 相册 --> <key>NSPhotoLibraryUsageDescription</key> <string>App需要您的同意,才能访问 ...

  5. 我的Java开发学习之旅------>工具类:Java使用正则表达式分离出字符串中的中文和英文

    今天看到一个工具类使用正则表达式将一大段字符串中的中文和英文都分离出来了,在此记录一下,读者可以收藏! import java.util.ArrayList; import java.util.Col ...

  6. 我的Android进阶之旅------>Android资源文件string.xml中\u2026的意思

    今天看了一个string.xml文件,对其中的一行代码中包含的\u2026不是很理解,后来查阅资料后发现了其中的意思. 代码如下: <resources xmlns:xliff="ur ...

  7. LeetCode:奇偶链表【328】

    LeetCode:奇偶链表[328] 题目描述 给定一个单链表,把所有的奇数节点和偶数节点分别排在一起.请注意,这里的奇数节点和偶数节点指的是节点编号的奇偶性,而不是节点的值的奇偶性. 请尝试使用原地 ...

  8. css 样式(checkbox开关、css按钮)

    checkbox开关 css .iosCheck { /* Blue edition */ } .iosCheck input { display: none; } .iosCheck i { dis ...

  9. windows下创建做一个类似与linux 的SFTP

    在项目中经常需要做通过ftp上传文件到ftp上,如果服务器是windows版的服务器又该如何做呢,下面就给大家介绍一个软件:freeSSHd 软件地址    http://www.freesshd.c ...

  10. Java对象 的创建与构造方法

    一.创建对象的四种方法: a. new语句: b. 利用反射,调用描述类的Class对象的newInstance()实例方法: c. 调用对象的clone(): d. 反序列化: 其中new 和 ne ...