java併發編程基礎(二)

1.Daemon線程

Daemon是一個支持型線程,他主要被用作程序中後臺調度以及支持性工作。

(Daemon屬性需要在啓動線程之前設置,不能在啓動線程之後設置)

Daemon`完成工作後,finally塊不一定執行

package cn.smallmartial.concurrency;

/**
 * @Author smallmartial
 * @Date 2019/8/23
 * @Email [email protected]
 */
public class Daemon {
    public static void main(String[] args) {
        Thread daemmonRunner = new Thread(new DaemonRunner(), "DaemmonRunner");
        daemmonRunner.setDaemon(true);
        daemmonRunner.start();
    }

    private static class DaemonRunner implements Runnable {
        @Override
        public void run() {
            try {
                SleepUtils.second(10);
            } catch (Exception e) {
                e.printStackTrace();
            }finally {
                System.out.println("finally run ...");
            }
        }
    }
}

在構建Daemon線程時,不能依靠finally塊中的內容來確保執行關閉或者清理資源的邏輯

2.線程中斷位

  • 中斷位可以理解爲線程的一個標識位屬性,他表示一個運行的線程是否被其他線程進行中斷操作。線程可以通過isInterrupted()進行判段是否被中斷,可以調用靜態方法Thread.interrupted對當前線程的中斷標識位進行復位。

  • 在java虛擬機中 在拋出InterruptedException之前,會將中斷位清除,isInterrupted()方法返回false。

    package cn.smallmartial.concurrency;
    
    import java.util.concurrent.TimeUnit;
    
    /**
     * @Author smallmartial
     * @Date 2019/8/23
     * @Email [email protected]
     */
    public class Interrupted {
        public static void main(String[] args) throws Exception {
            //不停的休眠
            Thread sleepThread = new Thread(new sleepRunner(), "sleepThread");
            sleepThread.setDaemon(true);
            //不停的運行
            Thread busyRunner = new Thread(new BusyRunner(), "BusyRunner");
            busyRunner.setDaemon(true);
            sleepThread.start();
            busyRunner.start();
            //休眠5秒 是兩個線程充分運行
            TimeUnit.SECONDS.sleep(5);
            sleepThread.interrupt();
            busyRunner.interrupt();
            System.out.println("sleepThread interrupted is "+ sleepThread.isInterrupted());
            System.out.println("busyThread interrupted is "+busyRunner.isInterrupted());
            SleepUtils.second(2);
        }
    
        static class sleepRunner implements Runnable{
    
            @Override
            public void run() {
                while (true){
                    SleepUtils.second(10);
                }
            }
        }
    
        static class BusyRunner implements Runnable{
    
            @Override
            public void run() {
                while (true){
                }
            }
        }
    }
    
    

3.過期的suspend()、resume()和stop()

這些api不建議使用,在調用後、線程不會釋放已佔有的資源(比如鎖),而是佔有者資源進入睡眠狀態,會引發死鎖狀態。

4.volatile和synchronized關鍵字

  • java支持多個線程同時訪問一個對象或者對象的成員變量,由於每個成員變量可以擁有這個變量的拷貝,所以在程序的執行過程中,一個線程看到的變量並不是最新的。
  • 關鍵字``volatile`可以用來修飾字段(成員變量),目的告知程序任何對改變量的訪問均需要從共享內存中獲取,而對他的改變必須同步刷新回共享內存,它能保證所有線程對變量的可見性。
  • 關鍵詞synochronized可以修飾方法或者以同步塊的形式使用,它主要確保多個線程在同一個時刻,只能有一個線程處於方法或者同步塊中,它保證了線程對變量的可見性和排他性。

5.對象、對象的監視器、同步隊列和執行線程之間的關係

任意線程對object訪問時(synchronized保護),首先要獲得Object的監視器,如果獲取失敗,線程則進入同步隊列,線程狀態變成blocked.當訪問前驅object釋放了鎖,則該釋放操作喚醒阻塞在同步隊列的線程,使其重新嘗試對監視器的獲取。

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