目录
守护线程
线程可见性
线程时序性
线程的中断机制
守护线程
基本概念
守护线程可以简单理解为后台运行线程,守护线程不需要关心他的结束问题。
java垃圾回收就是一个守护线程;例如你的应用程序运行时需要播放音乐,如果将播放音乐这个线程设置为非守护线程,那么用户请求退出时,不仅退出主线程,还要通知播放音乐的线程退出;如果设置为主线程就不需要了
写法
调用对象setDaemon(true)可设置为守护线程,该方法必须在启动前调用,当正在运行的线程都是守护线程时,java虚拟机退出。
使用
守护主动程序去使用的情况比较少,如java虚拟机,内存管理,数据库连接池,连接池本身包含后台线程,连接个数,超时时间,状态
线程可见性
从主内存复制变量到当前工作内存-执行代码改变共享变量的值-用工作内存数据刷新主内存相关内容
线程时序性
线程引用变量时不能直接从主内存中引用,如果线程工作内存中没有该变量,则会从主内存中拷贝一个副本到工作内存read-load,
在同一线程再度引用该字段时,有可能重新获取副本,也有可能引用原来的副本read-load-use顺序可由JVM实现系统决定,这时候线程与线程操作的先后顺序决定你程序对主内存区最后的修改是否正确
线程的中断机制
第一种方法:Thread.stop()已过时,不建议使用
第二种方法:利用interrupt()方法和机制
Thread提供3中中断线程的方法:
interrupt
public void interrupt()中断线程。
如果当前线程没有中断它自己(这在任何情况下都是允许的),则该线程的 checkAccess 方法就会被调用,这可能抛出 SecurityException。
如果线程在调用 Object 类的 wait()、wait(long) 或 wait(long, int) 方法,或者该类的 join()、join(long)、join(long, int)、sleep(long) 或 sleep(long, int) 方法过程中受阻,则其中断状态将被清除,它还将收到一个 InterruptedException。
如果该线程在可中断的通道上的 I/O 操作中受阻,则该通道将被关闭,该线程的中断状态将被设置并且该线程将收到一个 ClosedByInterruptException。
如果该线程在一个 Selector 中受阻,则该线程的中断状态将被设置,它将立即从选择操作返回,并可能带有一个非零值,就好像调用了选择器的 wakeup 方法一样。
如果以前的条件都没有保存,则该线程的中断状态将被设置。
中断一个不处于活动状态的线程不需要任何作用。
interrupted
public static boolean interrupted()测试当前线程是否已经中断。线程的中断状态 由该方法清除。换句话说,如果连续两次调用该方法,则第二次调用将返回 false(在第一次调用已清除了其中断状态之后,且第二次调用检验完中断状态前,当前线程再次中断的情况除外)。
线程中断被忽略,因为在中断时不处于活动状态的线程将由此返回 false 的方法反映出来。
isInterrupted
public boolean isInterrupted()测试线程是否已经中断。线程的中断状态 不受该方法的影响。
线程中断被忽略,因为在中断时不处于活动状态的线程将由此返回 false 的方法反映出来。
/**
* 线程中断
*/
public class ThreadDemo implements Runnable {
public static void main(String[] args) {
Thread thread = new Thread(new ThreadDemo(), "ThreadDemo");
System.out.println("Starting thread ...");
thread.start();
try {
Thread.sleep(3000);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("Interrupting Thread...");
thread.interrupt();
System.out.println("线程是否中断: " + thread.isInterrupted());
try {
Thread.sleep(3000);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("Stoping application...");
}
@Override
public void run() {
boolean stop = false;
while (!stop) {
System.out.println("线程开始运行...");
long time = System.currentTimeMillis();
while ((System.currentTimeMillis() - time < 1000)){
}
if (Thread.currentThread().isInterrupted()){
break;
}
try {
Thread.sleep(300L);
} catch (InterruptedException e) {
break;
}
}
System.out.println("线程退出请求 ...");
}
}