java线程控制、状态同步、volatile、Thread.interupt以及ConcurrentLinkedQueue
在有些严格的系统中,我们需要做到干净的停止线程并清理相关状态。涉及到这个主题会带出很多的相关点,简单的总结如下:
我们知道,在java中,有一个volatile关键字,其官方说明(https://docs.oracle.com/javase/tutorial/essential/concurrency/atomic.html)为:
Using volatile
variables reduces the risk of memory consistency errors, because any write to a volatile
variable establishes a happens-before relationship with subsequent reads of that same variable. This means that changes to a volatile
variable are always visible to other threads. What's more, it also means that when a thread reads a volatile
variable, it sees not just the latest change to the volatile
, but also the side effects of the code that led up the change.
基本可以认为,写入volatile变量的值对于其他线程总是可见,一个线程读取到volatile变量时,不仅其值是最新的,其他使用改变了判断的代码也会同时级联发生变化。
不过,volatile的范围仅限于每次从堆读取该值时,进入方法体内后,如果执行的时间较长或者一直处于循环,比如线程的run()方法内,期间对volatile的变更对方法体是不可见的,所以这一点需要注意,如果一定要有效,那就再包装个方法。
如果不想要再加个方法,可以考虑使用ConcurrentLinkedQueue,可以一开始为空,后面轮询判断status.poll() == null的方式实现。
第三,我们知道Thread有stop和interupt这两个终止线程的方法。因为stop已经@Deprecated,所以假设不会使用。再看interupt的副作用,对于很多程序比如log4j来说,其实使用interupt并无副作用,但有些情况下,使用interrupt会导致不必要的系统不一致性,看interrupt的javadoc,如下:
Unless the current thread is interrupting itself, which is always permitted, the checkAccess
method of this thread is invoked, which may cause a SecurityException
to be thrown.
If this thread is blocked in an invocation of the wait()
, wait(long)
, or wait(long, int)
methods of the Object
class, or of the join()
, join(long)
, join(long, int)
, sleep(long)
, or sleep(long, int)
, methods of this class, then its interrupt status will be cleared and it will receive an InterruptedException
.
If this thread is blocked in an I/O operation upon an interruptible channel
then the channel will be closed, the thread's interrupt status will be set, and the thread will receive a
ClosedByInterruptException
.
If this thread is blocked in a Selector
then the thread's interrupt status will be set and it will return immediately from the selection operation, possibly with a non-zero value, just as if the selector's wakeup
method were invoked.
If none of the previous conditions hold then this thread's interrupt status will be set.
Interrupting a thread that is not alive need not have any effect.
所以一般应使用前两种方法。
java线程控制、状态同步、volatile、Thread.interupt以及ConcurrentLinkedQueue的更多相关文章
- Thread线程源码解析,Java线程的状态,线程之间的通信
线程的基本概念 什么是线程 现代操作系统在运行一个程序的时候,会为其创建一个进程.例如,启动一个Java程序,操作系统就会创建一个Java进程.线代操作系统调度的最小单位是线程.也叫做轻量级进程.在一 ...
- Java线程的状态
Java线程的状态 线程对象在不同的运行时期有不同的状态,状态信息就存在于Thread中的State枚举中,如下所示: public enum State { /** * 至今尚未启动的线程处于这种状 ...
- java线程安全— synchronized和volatile
java线程安全— synchronized和volatile package threadsafe; public class TranditionalThreadSynchronized { pu ...
- Java线程演示样例 - 继承Thread类和实现Runnable接口
进程(Process)和线程(Thread)是程序执行的两个基本单元. Java并发编程很多其它的是和线程相关. 进程 进程是一个独立的执行单元,可将其视为一个程序或应用.然而,一个程序内部同事还包括 ...
- JAVA线程及简单同步实现的原理解析
线程 一.内容简介: 本文主要讲述计算机中有关线程的相关内容,以及JAVA中关于线程的基础知识点,为以后的深入学习做铺垫.如果你已经是高手了,那么这篇文章并不适合你. 二.随笔正文: 1.计算机系统组 ...
- Java线程中的同步
1.对象与锁 每一个Object类及其子类的实例都拥有一个锁.其中,标量类型int,float等不是对象类型,但是标量类型可以通过其包装类来作为锁.单独的成员变量是不能被标明为同步的.锁只能用在使用了 ...
- java线程和多线程同步
java的线程之间资源共享,所以会出现线程同步问题(即,线程安全) 一.线程创建: 方式①:extends java.lang.Thread,重写run(),run方法里是开启线程后要做的事..sta ...
- Java 线程控制
一.线程控制 和线程相关的操作都定义在Thread类中,但在运行时可以获得线程执行环境的信息.比如查看可用的处理器数目(这也行?): public class RunTimeTest { public ...
- Java 线程的状态
Java Thread的运行周期中, 有几种状态, 在 java.lang.Thread.State 中有详细定义和说明: NEW 状态是指线程刚创建, 尚未启动 RUNNABLE 状态是线程正在正常 ...
随机推荐
- 如何使用 App Studio 快速定制你自己的 Universal Windows App
之前我为大家介绍过 App Studio 这只神器可以帮助大家快速制作一个 Windows Phone 8 的应用,今天之所以在写一篇关于 App Studio 的文章是因为,App Studio 经 ...
- composer 安装使用
首先开启 php.ini ssl配置. 然后通过如下地址下载对应安装包安装即可:http://www.phpcomposer.com/ 当然如果安装失败,也可以下载 composer.phar 包 命 ...
- 制作便携版 FireFox 火狐浏览器
Firefox是一款可高度自定义的开源浏览器: 你可以访问 火狐DIY 定制自己的Firefox安装包, 此外,你还可以自己动手定制一款可以放在U盘随身携带的便携版Firefox火狐浏览器. 制作便携 ...
- Tomcat--配置tomcat,使其除了接受本地访问外,拒绝其他 IP 的访问
解决方案:修改server.xml文件,在</host>前添加代码: <Valve className="org.apache.catalina.valves.Remote ...
- DDD:两篇不错的文章
文章列表 Coding for Domain-Driven Design: Tips for Data-Focused Devs. Strengthening your domain: Aggrega ...
- 调用Ajax返回500错误的解决方法
看代码: public ActionResult UserLogin(LogOnModel model) { #region 验证码验证 #endregion OperationResult resu ...
- 基于openssl的单向和双向认证
1.前言 最近工作涉及到https,需要修改nginx的openssl模块,引入keyless方案.关于keyless可以参考CloudFlare的官方博客: https://blog.cloudfl ...
- ASP.NET中WebService的两种身份验证方法
一.通过SOAP Header身份验证 此方法是通过设置SOAP Header信息来验证身份,主要通过以下几步: 1.在服务端实现一个SOAP Header类 public class Credent ...
- IOS7中自动计算label的宽度和高度的方法
#import "ViewController.h" @implementation ViewController - (void)viewDidLoad { [super vie ...
- codevs4247奇特的生物 解析报告
4247 奇特的生物 时间限制: 1 s 空间限制: 128000 KB 题目等级 : 钻石 Diamond 题解 题目描述 Description 科学家们最近发现了一种奇怪的生物,它们每天长大一岁 ...