一。关于终止线程stop与interrupt

  一般来说,线程执行结束后就变成消亡状态,乍看之下我们并不需要人为进行干预(人为停止线程),不过凡事都有例外吧,在服务器或者其他应用场景下,线程为了提供服务而一直在不停的运转,因此必要时刻我们还需“人为干涉的”。

  通常情况下,终止线程有两种方式:stop与interrupt

  1) stop:暴力的停止线程(不管线程执行到哪段代码,立刻干掉),这个方法因为过于暴力会导致安全问题,因此JDK不推荐使用。

  2) interrupt:优雅停止,调用该方法会通知线程可以进行停止操作了,此时线程只是变成可停止状态(thread.isInterrupted的值为true),实际上并没有停止

  请看下段代码:

  

 package com.bdqn.lyrk.basic;

 /**
* 一个线程设置共享变量的值,保持ID与name值相同
* 另外一个线程读取共享变量的值,发现ID与name值不同时打印
*
* @author chen.nie
* @date 2018/1/30
**/
public class StopThreadUnsafe { public static User user = new User(); public static class User {
private int id;
private String name; public int getId() {
return id;
} public void setId(int id) {
this.id = id;
} public String getName() {
return name;
} public void setName(String name) {
this.name = name;
} public User() {
id = 0;
name = "0";
} @Override
public String toString() {
return "User [id=" + id + ",name=" + name + "]";
}
} public static class ChangeObjectThread extends Thread { @Override
public void run() {
while (true) {
synchronized (user) {
if (Thread.currentThread().isInterrupted()) {
break;
}
int i = (int) System.currentTimeMillis() / 1000;
user.setId(i);
try {
Thread.sleep(100);
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
}
user.setName("" + i); }
Thread.yield();
}
}
} public static class ReadObjectThread extends Thread { @Override
public void run() {
while (true) {
synchronized (user) {
if (user.getId() != Integer.parseInt(user.getName())) {
System.out.println(user);
}
}
Thread.yield();
}
}
}
}

  Main方法:

 package com.bdqn.lyrk.basic;

 public class Main {
public static void main(String[] args) throws InterruptedException {
new StopThreadUnsafe.ReadObjectThread().start();
while (true) {
StopThreadUnsafe.ChangeObjectThread thread = new StopThreadUnsafe.ChangeObjectThread();
thread.start();
Thread.sleep(200);
thread.stop();
// thread.interrupt();
}
}
}

  此时调用stop终止线程时,得到如下结果

  

User [id=1197577,name=1197576]
User [id=1197577,name=1197576]
User [id=1197577,name=1197576]
User [id=1197577,name=1197576]
User [id=1197578,name=1197577]

原因很简单:stop方法会释放对象锁,并终止线程,当线程还没有与name赋值时,已经被干掉了因此其他线程在读取时,很有可能读到NAME与ID值不一致的情况

二。守护线程Daemon

守护线程顾名思义,是系统的守护者,这个线程为系统的运行默默提供服务,当系统任务运行完毕,守护线程也就完成使命了,比如说垃圾回收线程,JIT线程都是守护线程,设置守护线程的方式:在调用start方法前,通过线程对象.setDaemon(true)

代码如下:

 package com.bdqn.lyrk.basic;

 public class DaemonDemo {
public static class DaemonT extends Thread {
@Override
public void run() {
while (true){
System.out.println("I am alive");
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
} public static void main(String[] args) throws InterruptedException {
DaemonT daemonT = new DaemonT();
daemonT.setDaemon(true);
daemonT.start();
Thread.sleep(5000);
}
}

运行结果

I am alive
I am alive
I am alive
I am alive
I am alive Process finished with exit code 0

我们可以看到,当主线程执行完毕后,守护线程也随之结束

三。wait与notify

  wait与notify是多线程协同工作的最基本手段,可是这两个方法属于Object的方法,当需要使用wait和notify时,必须配合synchronized使用,此时调用wait方法,当前线程会进入等待队列并释放当前的对象锁,直到线程被唤醒(notify),notify方法会随机唤醒一个在等待队列中的线程,notifyAll方法则唤醒所有在等待队列中的线程

代码示例:

 package com.bdqn.lyrk.basic;

 public class SimpleWN {
public static final Object object = new Object(); public static class T1 extends Thread { @Override
public void run() {
synchronized (object) {
System.out.println("开始执行线程...");
try {
object.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("结束执行线程...");
}
}
} public static class T2 extends Thread {
@Override
public void run() {
synchronized (object) {
System.out.println("5秒后准备唤醒线程..");
try {
Thread.sleep(5000);
} catch (InterruptedException e) {
e.printStackTrace();
}
object.notify();
}
}
} public static void main(String[] args) {
T1 t1 = new T1();
T2 t2 = new T2();
t1.start();
t2.start();
}
}

输出内容:

开始执行线程...
5秒后准备唤醒线程..
结束执行线程... Process finished with exit code 0

注意以下几点:

1)当线程T1被notify过后,也必须要重新获取对象锁,才能够继续执行

2)sleep也能达到wait的效果,但是唯一区别时,sleep时并不会释放对象锁,因此其他线程并没有得到执行的机会

关于java线程中stop interrupt daemon wait notify的更多相关文章

  1. java线程中的sleep/wait/notify/yield/interrupt方法 整理

    java线程中的sleep/wait/notify/yield/interrupt方法 sleep 该方法能够使当前线程休眠一段时间 休眠期间,不释放锁 休眠时间结束之后,进入可执行状态,加入到线程就 ...

  2. java线程中的interrupt,isInterrupt,interrupted方法

    在java的线程Thread类中有三个方法,比较容易混淆,在这里解释一下 (1)interrupt:置线程的中断状态 (2)isInterrupt:线程是否中断 (3)interrupted:返回线程 ...

  3. java线程中的sleep和wait区别

                                                                            面试题:java线程中sleep和wait的区别以及其资 ...

  4. Java 线程的终止-interrupt

    Java线程的终止——interrupt 取消/关闭的场景 我们知道,通过线程的start方法启动一个线程后,线程开始执行run方法,run方法运行结束后线程退出,那为什么还需要结束一个线程呢?有多种 ...

  5. 在Java 线程中返回值的用法

    http://icgemu.iteye.com/blog/467848 在Java 线程中返回值的用法 博客分类: Java Javathread  有时在执行线程中需要在线程中返回一个值:常规中我们 ...

  6. 并发编程——线程中sleep(),yield(),join(),wait(),notify(),notifyAll()区别

    前言 今天简单的讲一讲线程中sleep(),join(),yield(),wait(),notify(),notifyAll()这些方法的使用以及区别. 不过在讲这些方法之前,需要简单的介绍一下锁池和 ...

  7. 停止Java线程,小心interrupt()方法

    来源:http://blog.csdn.net/wxwzy738/article/details/8516253 程序是很简易的.然而,在编程人员面前,多线程呈现出了一组新的难题,如果没有被恰当的解决 ...

  8. Java - 线程Join与interrupt

    Java多线程系列--“基础篇”08之 join() 概要 本章,会对Thread中join()方法进行介绍.涉及到的内容包括:1. join()介绍2. join()源码分析(基于JDK1.7.0_ ...

  9. 为什么JAVA线程中没有Running状态?

    面试官问:为什么 Java 线程没有 Running 状态?我懵了 —— 转  芋道源码 什么是 RUNNABLE? 与传统的ready状态的区别 与传统的running状态的区别 当I/O阻塞时 如 ...

随机推荐

  1. ExtJs6级联combo的实现

    父类获取子类进行操作 { xtype: 'combo', store: Common.Dic.getDicData("IMAGE_BIG_TYPE") , multiSelect: ...

  2. monog和github学习

    1.导出服务器数据库到本地以json的格式储存:mongoexport -h ip -d dbname -c user -o D:\mondb\user.json2.导入本地Json到本地项目中:D: ...

  3. JQ.ajax 各种参数及属性设置 ( 转载 )

    $.ajax({      type: "post",      url: url,      dataType:'html',      success: function(da ...

  4. Vue全家桶

    简介 “简单却不失优雅,小巧而不乏大匠”. Vue.js 是一个JavaScriptMVVM库,是一套构建用户界面的渐进式框架.它是以数据驱动和组件化的思想构建的,采用自底向上增量开发的设计. 为什么 ...

  5. JAVA通过注解处理器重构代码,遵循单一职责

    前言:最近在看一个内部网关代码的时候,发现处理Redis返回数据这块写的不错,今天有时间好好研究下里面的知识点. 业务流程介绍: #项目是采用Spring Boot框架搭建的.定义了一个@Redis注 ...

  6. Codeforces Round #436 (Div. 2) D. Make a Permutation!

    http://codeforces.com/contest/864/problem/D 题意: 给出n和n个数(ai <= n),要求改变其中某些数,使得这n个数为1到n的一个排列,首先保证修改 ...

  7. hdu-2141 Can you find it?---暴力+二分

    题目链接: http://acm.hdu.edu.cn/showproblem.php?pid=2141 题目大意: 给ABC三个数组,给一个X,求是否存在Ai+Bj+Ck = X 思路: 等式转化成 ...

  8. Canvas绘制五角星

    from tkinter import * import math as m root = Tk() w = Canvas(root, width=200, height=100, backgroun ...

  9. hue集成hbase出现TSocket read 0 bytes

    解决办法:修改hbase的配置文件 添加以下配置 https://stackoverflow.com/questions/20415493/api-error-tsocket-read-0-bytes ...

  10. WPF 字符串溢出判断,字符串长度是否超过控件宽度

    TextBloc可以将TextTrimming属性设置为CharacterEllipsis 其他控件可以在控件大小变更或者其他事件上附加下列方法 private void OnEllipsis(obj ...