天天看點

Java多線程設計

作業系統在運作一個程式時候,會首先建立一個程序。如果啟動一個java程式就會建立一個java程序。現代作業系統的排程的最小機關是線程,也叫輕量級程序。一個程序中可以建立多個線程。香河縣線程都擁有自己各自的計數器,堆棧,和局部變量等屬性,并且能夠共享通路記憶體變量。處理器在這些線程上高速切換,讓你我感覺到是在并行執行。

在java運作時候不隻是啟動一個main線程運作,請看一下下邊的例子

運作結果

為什麼要用多線程,也就是一個字“快”,天下程式唯快不破

1.可以利用多個處理器的核心

2.更快的響應時間:

有時候我麼會寫一些比較複雜的業務代碼。比如:一筆訂單的建立,包括插入訂單資料,生成訂單快照,發送郵件通知賣家,記錄貨品銷售數量等,使用者從單擊訂購按鈕開始,就要等待這些操作全部完成看到訂購成功的結果,但是這麼多的業務操作如何能快速的完成就是用多線程處理,縮短了相應的時間,提升了使用者的體驗。

3.更好的程式設計模型

要研究多線程我們先要知道多線程的監控如何做。大家都知道多線程的子產品在普通沒有經驗的程式員來說就不知到哪裡有問題。是以我們這裡先要學會如何利用工具來看看運作的情況。

先上一段代碼:

/**
 * java線程在8個狀态之間變切
 * New,Runnable,Running,Waiting,Time_Waiting,Ready,Terminated,blocked
 *
 * @author Janle
 *
 */
public class Test {
	public static void main(String[] args) {
		new Thread(new TimeWaiting(), "TimeWaitingThread").start();
		new Thread(new Waiting(), "WaitingThread").start();
		new Thread(new Blocked(),"BlockedThread-1").start();
		new Thread(new Blocked(),"BlockedThread-2").start();
	}

	// 該線程不斷地進行睡眠
	static class TimeWaiting implements Runnable {
		@Override
		public void run() {
			while (true) {
				SleepUtils.second(100);
			}
		}
	}

	// 該線程在Waiting執行個體上等待
	static class Waiting implements Runnable {
		@Override
		public void run() {
			while (true) {
				synchronized (Waiting.class) {
					try {
						Waiting.class.wait();
					} catch (InterruptedException e) {
						e.printStackTrace();
					}
				}
			}
		}
	}

	// 該線程在Blocked執行個體上加鎖後不會釋放該鎖
	static class Blocked implements Runnable {
		@Override
		public void run() {
			synchronized (Blocked.class) {
				while (true) {
					SleepUtils.second(100);
				}
			}
		}

	}
}

class SleepUtils {
	public static final void second(long seconds) {
		try {
			TimeUnit.SECONDS.sleep(seconds);
		} catch (InterruptedException e) {
			e.printStackTrace();
		}
	}
}
           

這裡我們jps一下找到對應的pid。

10272 Jps
11816 Test
14600
           

使用jstack pid來看看jstack 11816

//銷毀的jvm處于運作狀态
"DestroyJavaVM" #14 prio=5 os_prio=0 tid=0x000000000279a000 nid=0x243c waiting on condition [0x0000000000000000]
   java.lang.Thread.State: RUNNABLE
//BlockedThread-2線程阻塞在擷取的Blocked.class示例的鎖上
"BlockedThread-2" #13 prio=5 os_prio=0 tid=0x00000000188a1000 nid=0x3100 waiting for monitor entry [0x000000001963f000]
   java.lang.Thread.State: BLOCKED (on object monitor)
        at com.lenovo.lenjoy.Test$Blocked.run(Test.java:52)
        - waiting to lock <0x00000000d5f5b238> (a java.lang.Class for com.lenovo.lenjoy.Test$Blocked)
        at java.lang.Thread.run(Thread.java:745)
//BlockedThread-1獲得到了Blocked.class的鎖
"BlockedThread-1" #12 prio=5 os_prio=0 tid=0x00000000188a0800 nid=0x16e0 waiting on condition [0x000000001953f000]
   java.lang.Thread.State: TIMED_WAITING (sleeping)
        at java.lang.Thread.sleep(Native Method)
        at java.lang.Thread.sleep(Thread.java:340)
        at java.util.concurrent.TimeUnit.sleep(TimeUnit.java:386)
        at com.lenovo.lenjoy.SleepUtils.second(Test.java:63)
        at com.lenovo.lenjoy.Test$Blocked.run(Test.java:52)
        - locked <0x00000000d5f5b238> (a java.lang.Class for com.lenovo.lenjoy.Test$Blocked)
        at java.lang.Thread.run(Thread.java:745)
//WaitingThread線程在Waiting執行個體上等待
"WaitingThread" #11 prio=5 os_prio=0 tid=0x0000000018872800 nid=0x254c in Object.wait() [0x000000001943e000]
   java.lang.Thread.State: WAITING (on object monitor)
        at java.lang.Object.wait(Native Method)
        - waiting on <0x00000000d5f54058> (a java.lang.Class for com.lenovo.lenjoy.Test$Waiting)
        at java.lang.Object.wait(Object.java:502)
        at com.lenovo.lenjoy.Test$Waiting.run(Test.java:37)
        - locked <0x00000000d5f54058> (a java.lang.Class for com.lenovo.lenjoy.Test$Waiting)
        at java.lang.Thread.run(Thread.java:745)
//TimeWaitingThread線程處理逾時等待
"TimeWaitingThread" #10 prio=5 os_prio=0 tid=0x0000000018897800 nid=0x28a4 waiting on condition [0x000000001933f000]
   java.lang.Thread.State: TIMED_WAITING (sleeping)
        at java.lang.Thread.sleep(Native Method)
        at java.lang.Thread.sleep(Thread.java:340)
        at java.util.concurrent.TimeUnit.sleep(TimeUnit.java:386)
        at com.lenovo.lenjoy.SleepUtils.second(Test.java:63)
        at com.lenovo.lenjoy.Test$TimeWaiting.run(Test.java:25)
        at java.lang.Thread.run(Thread.java:745)

"Service Thread" #9 daemon prio=9 os_prio=0 tid=0x000000001744e800 nid=0x24d0 runnable [0x0000000000000000]
   java.lang.Thread.State: RUNNABLE

"C1 CompilerThread2" #8 daemon prio=9 os_prio=2 tid=0x0000000017421800 nid=0x4f4 waiting on condition [0x0000000000000000]
   java.lang.Thread.State: RUNNABLE

"C2 CompilerThread1" #7 daemon prio=9 os_prio=2 tid=0x000000001741e800 nid=0x203c waiting on condition [0x0000000000000000]
   java.lang.Thread.State: RUNNABLE

"C2 CompilerThread0" #6 daemon prio=9 os_prio=2 tid=0x000000001741c000 nid=0x36d0 waiting on condition [0x0000000000000000]
   java.lang.Thread.State: RUNNABLE

"Attach Listener" #5 daemon prio=5 os_prio=2 tid=0x000000001741b000 nid=0x7a4 waiting on condition [0x0000000000000000]
   java.lang.Thread.State: RUNNABLE

"Signal Dispatcher" #4 daemon prio=9 os_prio=2 tid=0x000000001741a000 nid=0x3140 runnable [0x0000000000000000]
   java.lang.Thread.State: RUNNABLE

"Finalizer" #3 daemon prio=8 os_prio=1 tid=0x0000000002888000 nid=0x26dc in Object.wait() [0x000000001873f000]
   java.lang.Thread.State: WAITING (on object monitor)
        at java.lang.Object.wait(Native Method)
        - waiting on <0x00000000d6090180> (a java.lang.ref.ReferenceQueue$Lock)
        at java.lang.ref.ReferenceQueue.remove(ReferenceQueue.java:142)
        - locked <0x00000000d6090180> (a java.lang.ref.ReferenceQueue$Lock)
        at java.lang.ref.ReferenceQueue.remove(ReferenceQueue.java:158)
        at java.lang.ref.Finalizer$FinalizerThread.run(Finalizer.java:209)

"Reference Handler" #2 daemon prio=10 os_prio=2 tid=0x00000000173b8000 nid=0x2df4 in Object.wait() [0x000000001863f000]
   java.lang.Thread.State: WAITING (on object monitor)
        at java.lang.Object.wait(Native Method)
        - waiting on <0x00000000d6088210> (a java.lang.ref.Reference$Lock)
        at java.lang.Object.wait(Object.java:502)
        at java.lang.ref.Reference$ReferenceHandler.run(Reference.java:157)
        - locked <0x00000000d6088210> (a java.lang.ref.Reference$Lock)

"VM Thread" os_prio=2 tid=0x00000000173b6800 nid=0x3684 runnable

"GC task thread#0 (ParallelGC)" os_prio=0 tid=0x00000000027b0000 nid=0x2cc4 runnable

"GC task thread#1 (ParallelGC)" os_prio=0 tid=0x00000000027b1800 nid=0xf00 runnable

"GC task thread#2 (ParallelGC)" os_prio=0 tid=0x00000000027b3800 nid=0x9d0 runnable

"GC task thread#3 (ParallelGC)" os_prio=0 tid=0x00000000027b5000 nid=0x2918 runnable

"VM Periodic Task Thread" os_prio=2 tid=0x00000000187de800 nid=0x1c40 waiting on condition

JNI global references: 7