java-多線程管理-主動/被動停止,鎖

多線程管理-主動或被動停止線程

  • 線程被動地暫停和終止
    – 依靠別的線程來拯救自己
    – 沒有及時釋放資源
    在生產者/消費者示例中,線程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();
            }
        }
    }
}

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章