java併發基礎--線程

線程信息查看

public class ThreadInfoTest {

public static void main(String[] args) {

//獲取java線程管理mxbean

ThreadMXBean threadMXBean = ManagementFactory.getThreadMXBean();

//不需要獲取同步的monitor和synchronizer信息 僅獲取線程和線程堆棧

ThreadInfo[] threadInfos = threadMXBean.dumpAllThreads(false, false);

for (ThreadInfo threadInfo : threadInfos) {

System.out.println("[" + threadInfo.getThreadId() + "]" + threadInfo.getThreadName() );

}

}

}
[9]Monitor Ctrl-Break
[5]Attach Listener
[4]Signal Dispatcher
[3]Finalizer
[2]Reference Handler
[1]main  用戶程序入口

可以看到一個java程序運行不僅僅是main()方法運行,而是main線程和多個其他線程同時運行.

線程的狀態

public static void main(String[] args) {

    new Thread(new TimeWaiting(),"TimeWaitingThread").start();
    new Thread(new Waiting(),"waitingthread").start();
    new Thread(new Blocked(),"blocked thread -1 ").start();
    new Thread(new Blocked(),"blocked thread -2 ").start();
}


static class TimeWaiting implements Runnable {

    @Override
    public void run() {
        while (true){
            try {
                TimeUnit.SECONDS.sleep(12);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }
}



static class  Waiting implements Runnable{

    @Override
    public void run() {
        while (true){
            synchronized (Waiting.class){
                try {
                    Waiting.class.wait();
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        }
    }
}


static class Blocked implements Runnable{

    @Override
    public void run() {
        synchronized (Blocked.class){
            while (true){
                try {
                    TimeUnit.SECONDS.sleep(12);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        }
    }
}
"blocked thread -2 " prio=6 tid=0x00000000070f2800 nid=0x1c14 waiting for monitor entry [0x0000000007eff000]  
**blocked thread -2 阻塞在獲取鎖上**
   java.lang.Thread.State: BLOCKED (on object monitor)
    at concurrent.ThreadState$Blocked.run(ThreadState.java:60)
    - waiting to lock <0x000000077e351470> (a java.lang.Class for concurrent.ThreadState$Blocked)
    at java.lang.Thread.run(Thread.java:662)

"blocked thread -1 " prio=6 tid=0x00000000070c5800 nid=0x14bc waiting on condition [0x0000000007dff000]
**blocked thread -1 獲取到了鎖**
   java.lang.Thread.State: TIMED_WAITING (sleeping)
    at java.lang.Thread.sleep(Native Method)
    at java.lang.Thread.sleep(Thread.java:302)
    at java.util.concurrent.TimeUnit.sleep(TimeUnit.java:328)
    at concurrent.ThreadState$Blocked.run(ThreadState.java:60)
    - locked <0x000000077e351470> (a java.lang.Class for concurrent.ThreadState$Blocked)
    at java.lang.Thread.run(Thread.java:662)

"waitingthread" prio=6 tid=0x00000000070c4800 nid=0x1c38 in Object.wait() [0x0000000007cff000]
   java.lang.Thread.State: WAITING (on object monitor)
    at java.lang.Object.wait(Native Method)
    - waiting on <0x000000077e34cc88> (a java.lang.Class for concurrent.ThreadState$Waiting)
    at java.lang.Object.wait(Object.java:485)
    at concurrent.ThreadState$Waiting.run(ThreadState.java:43)
    - locked <0x000000077e34cc88> (a java.lang.Class for concurrent.ThreadState$Waiting)
    at java.lang.Thread.run(Thread.java:662)

"TimeWaitingThread" prio=6 tid=0x0000000007148800 nid=0x1718 waiting on condition [0x0000000007bff000]
**該線程處於超時等待**
   java.lang.Thread.State: TIMED_WAITING (sleeping)
    at java.lang.Thread.sleep(Native Method)
    at java.lang.Thread.sleep(Thread.java:302)
    at java.util.concurrent.TimeUnit.sleep(TimeUnit.java:328)
    at concurrent.ThreadState$TimeWaiting.run(ThreadState.java:26)
    at java.lang.Thread.run(Thread.java:662)

java線程在運行的生命週期中可能處於6中不同的狀態,在給定的一個時刻線程只能處於其中的一個狀態.

狀態名稱 說明
NEW 初始狀態線程被構建但是還沒有調用start()方法
Runnable 運行狀態java線程將操作系統中的就緒和運行倆種狀態統稱爲運行中
BLOCKED 阻塞狀態 表示線程阻塞於鎖
WAITING 等待狀態 表示線程進入等待狀態 進入該狀態表示當前線程需要等待其他線程做出一些特定的動作 例如通知或中斷
TIME_WAITING 超時等待狀態 該狀態不同於waiting 他是可以在指定的時間自行返回的
TERMINATED 終止狀態 表示當前線程已經執行完畢

這裏寫圖片描述

知識點:

阻塞狀態是線程阻塞在進入synchronized關鍵字修飾的方法或代碼塊時的狀態,但是阻塞在java.concurrent包中Lock接口的線程狀態卻是等待狀態,因爲java.concurrent中的Lock接口對於阻塞的實現均實現了LockSupport類中的相關方法.

Daemon線程

Daemon線程是一種支持型線程 因爲它主要被用作程序中後臺調度以及支持性工作 這意味着 當一個java虛擬機中不存在非daemon線程的時候 java虛擬機將會退出

public static void main(String[] args) {
        Thread thread = new Thread(new DaemonRunner(),"daemon runner");
        thread.setDaemon(true);
        thread.start();
    }


    static class DaemonRunner implements Runnable {

        @Override
        public void run() {
            try {
                TimeUnit.SECONDS.sleep(10);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }finally {
                System.out.println("daemon thread finally run");
            }
        }
    }

main線程啓動了Daemonrunner之後main方法執行完畢結束 此時jvm中沒有非Daemon線程 jvm需要退出 jvm中的所有Daemon線程立即終止

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

線程中斷

    public static void main(String[] args) throws InterruptedException {
        Thread busyThread = new Thread(new BusyRunner(),"busythread");
        busyThread.setDaemon(true);
        Thread sleepThread = new Thread(new SleepRunner(),"sleeprunner");
        sleepThread.setDaemon(true);
        busyThread.start();
        sleepThread.start();

        TimeUnit.SECONDS.sleep(6);

        busyThread.interrupt();
        sleepThread.interrupt();

        System.out.println("busythread isinterrupe is :" + busyThread.isInterrupted());
        System.out.println("sleepThread isinterrupe is :" + sleepThread.isInterrupted());
        TimeUnit.SECONDS.sleep(6);
    }

    static class SleepRunner implements  Runnable {

        @Override
        public void run() {

            try {
                TimeUnit.SECONDS.sleep(10);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }

    static class BusyRunner implements  Runnable {

        @Override
        public void run() {
            while (true){

            }
        }
    }

知識:
java中聲明拋出InterruptedException的方法 這些方法在拋出InterruptException之前java虛擬機會先將該線程中的中斷標示位清除 然後拋出異常 此時調用isinterrupted 方法將會返回false

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