多线程管理-主动或被动停止线程
- 线程被动地暂停和终止
– 依靠别的线程来拯救自己
– 没有及时释放资源
– 在生产者/消费者示例中,线程wait的时候,需要靠别的线程来notify,只有notify了,其他线程才能从wait的状态解脱出来,这样线程就是被动的暂停和终止,这种情况很危险,例如线程打开了一个文件,或者拿着某一个锁对象,一旦进入wait状态,锁或者文件不能够及时的释放资源,可以使用定期监测共享变量,当共享变量变为某种状态时,先释放资源,再暂停或者终止。 - 线程主动暂停和终止
– 定期检测共享变量
– 如果需要暂停或者终止,先释放资源,再主动动作
– 暂停:Thread.sleep(),休眠
– 终止:run方法结束,线程终止
主动、被动停止线程示例:
interrupted()是Thread类的方法,用来测试当前线程是否收到一个INTERRUPT的信号。如果收到,该方法返回true,否则返回false。
package interrupt;
/**
* @ClassName:InterruptTest
* @Description:
* @author: Torey
*/
public class InterruptTest {
public static void main(String[] args) throws InterruptedException {
//
TestThread1 t1 = new TestThread1();
TestThread2 t2 = new TestThread2();
t1.start();
t2.start();
//让线程运行一会后中断
Thread.sleep(2000);
//interrupt 是让线程中断
//被动停止
t1.interrupt();
//主动停止
t2.flag=false;
System.out.println("main thread is exiting");
}
}
/**
* 被动的停止
*/
class TestThread1 extends Thread{
@Override
public void run() {
//判断标志,当本线程被被别人interrupt后,JVM会被本线程设置interrupted标记
//interrupted()是Thread类的方法,用来测试当前线程是否收到一个interrupt的信号。
// 如果收到,该方法返回true,否则返回false.
//这里是被动的停止线程
while (!interrupted()) {
System.out.println("test thread1 is running");
try{
Thread.sleep(1000);
}catch (Exception ex){
ex.printStackTrace();
break;
}
}
}
}
/**
* 主动的停止
*/
class TestThread2 extends Thread{
public volatile boolean flag=true;
@Override
public void run(){
//判断标志,当本线程被别人interrupt后,JVM被本线程设置interrupted标记
//这里是主动停止线程
while (flag) {
System.out.println("test thread2 is running");
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
System.out.println("test thread2 is exitting");
}
}
多线程管理-锁,守护线程
- 多线程死锁
– 每个线程互相持有别人需要的锁(哲学家吃面问题)
– 预防死锁,对资源进行等级排序 - 守护(后台)线程
– 普通线程的结束,是run方法运行结束
– 守护线程的结束,是run方法运行结束,或main函数结束
– 守护线程永远不要访问资源,如文件或数据库等 - 线程查看工具jvisualvm
死锁实例:
package deadlock;
import java.util.concurrent.TimeUnit;
/**
* @ClassName:ThreadDemo5
* @Description:死锁测试
* @author: Torey
*/
public class ThreadDemo5 {
public static Integer r1=1;
public static Integer r2=2;
public static void main(String[] args){
TestThread51 t1 = new TestThread51();
t1.start();
TestThread52 t2 = new TestThread52();
t2.start();
}
}
class TestThread51 extends Thread{
@Override
public void run(){
//避免死锁,就需要等资源进行等级排序加锁
// synchronized (ThreadDemo5.r1){
synchronized (ThreadDemo5.r2){
try {
TimeUnit.SECONDS.sleep(3);
} catch (InterruptedException e) {
e.printStackTrace();
}
// synchronized (ThreadDemo5.r1){
synchronized (ThreadDemo5.r2){
System.out.println("TestThread51 is running");
}
}
}
}
class TestThread52 extends Thread{
@Override
public void run(){
synchronized (ThreadDemo5.r1){
try {
//TimeUnit是JDK5 引入的新类,位于java.util.concurrent包中
//它提供了时间单位和一些时间转换、计时和延迟等函数
//这里是睡眠3秒
TimeUnit.SECONDS.sleep(3);
} catch (InterruptedException e) {
e.printStackTrace();
}
synchronized (ThreadDemo5.r2){
System.out.println("TestThread52 is running");
}
}
}
}
命令输入jvisualvm,查看是否有死锁
守护线程
守护线程的结束,是run方法运行结束,或main函数结束
package daemon;
/**
* @ClassName:ThreadDemo4
* @Description:
* @author: Torey
*/
public class ThreadDemo4 {
public static void main(String[] args) throws InterruptedException {
TestThread4 t = new TestThread4();
//setDaemon(true) 设置守护线程
t.setDaemon(true);
t.start();
Thread.sleep(2000);
System.out.println("main thread is exiting");
}
}
class TestThread4 extends Thread{
@Override
public void run(){
while (true){
System.out.println("TestThread4 is running");
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}