了解線程由來
單核CPU之所以能夠?qū)崿F(xiàn)多進(jìn)程,主要是依賴操作系統(tǒng)的進(jìn)程調(diào)度算法。如時(shí)間片輪轉(zhuǎn)算法,可以實(shí)現(xiàn)QQ、微信、瀏覽器同時(shí)運(yùn)行,從而實(shí)現(xiàn)多進(jìn)程。
隨著計(jì)算機(jī)技術(shù)的發(fā)展,進(jìn)程出現(xiàn)很多弊端,一是由于進(jìn)程是資源擁有者,創(chuàng)建、撤消與切換存在較大的時(shí)空開銷,因此需要引入輕量進(jìn)程; 二是由于對(duì)稱多處理機(jī)出現(xiàn),可以滿足多個(gè)運(yùn)行單位,而多個(gè)進(jìn)程并行開銷過大。
因此在80年代,出現(xiàn)了能獨(dú)立運(yùn)行的基本單位 --- 線程。
從單核到多核
最初計(jì)算機(jī)是單任務(wù)的,然后發(fā)展到多任務(wù),接著出現(xiàn)多線程并行,同時(shí)計(jì)算機(jī)也從單cpu進(jìn)入到多cpu。如下圖
多任務(wù):其實(shí)就是利用操作系統(tǒng)時(shí)間片輪轉(zhuǎn)使用的原理。操作系統(tǒng)通過將cpu的執(zhí)行時(shí)間分割成多個(gè)時(shí)間片,為每個(gè)任務(wù)分配時(shí)間片,因?yàn)閏pu處理速度很快,這樣就用戶看來好像每個(gè)任務(wù)都在同時(shí)執(zhí)行,感覺有多個(gè)cpu,但本質(zhì)上一個(gè)時(shí)間點(diǎn)只有一個(gè)任務(wù)在運(yùn)行。
為什么會(huì)有線程?
線程切換比進(jìn)程切換速度會(huì)快
在什么場(chǎng)景下使用多線程?
通過并行計(jì)算提高程序性能
等待網(wǎng)絡(luò)、IO響應(yīng)導(dǎo)致的耗時(shí)時(shí)間問題
線程的分類有哪些?
用戶線程、內(nèi)核線程、混合式
進(jìn)程和線程的關(guān)系?
根本區(qū)別:進(jìn)程是資源分配的最小單位,線程是CPU調(diào)度的最小單位
進(jìn)程是一個(gè)應(yīng)用程序在處理機(jī)上的一次執(zhí)行過程,它是一個(gè)動(dòng)態(tài)概念,而線程是進(jìn)程中的一部分,進(jìn)程包含多個(gè)線程在運(yùn)行。
開銷:每個(gè)進(jìn)程都有獨(dú)立的代碼和數(shù)據(jù)空間,程序之間的切換會(huì)有較大的開銷;線程可以看做輕量級(jí)的進(jìn)程,同一類線程共享代碼和數(shù)據(jù)空間,每個(gè)線程都有自己獨(dú)立的運(yùn)行棧和程序計(jì)數(shù)器,線程之間切換的開銷小。
內(nèi)存分配:系統(tǒng)在運(yùn)行的時(shí)候會(huì)為每個(gè)進(jìn)程分配不同的內(nèi)存空間,則線程除了CPU之外,系統(tǒng)不會(huì)為線程分配內(nèi)存,線程組之是只能共享資源。
線程的實(shí)現(xiàn)方法有哪些
Thread、Runnable、Callable/future
線程的狀態(tài)有哪些
NEW 新建
READY 就緒
RUNNABLE 運(yùn)行
BLOCKED 阻塞
? 等待阻塞 wait
? 同步阻塞 ?synchronized
? 其他阻塞 sleep/join
WAITING 等待
TIMED_WAITING 超時(shí)等待
TERMINATED 終止
線程狀態(tài)圖如下:
?查看線程狀態(tài)的代碼如下:
public class ThreadStatusDemo {
? ?public static void main(String[] args) {
? ? ? ?new Thread(()->{
? ? ? ? ? ?while (true){
? ? ? ? ? ? ? ?try {
? ? ? ? ? ? ? ? ? ?TimeUnit.SECONDS.sleep(100);
? ? ? ? ? ? ? ?} catch (InterruptedException e) {
? ? ? ? ? ? ? ? ? ?e.printStackTrace();
? ? ? ? ? ? ? ?}
? ? ? ? ? ?}
? ? ? ?},"timewaiting").start();
? ? ? ?new Thread(()->{
? ? ? ? ? while (true){
? ? ? ? ? ? ? synchronized (ThreadStatusDemo.class){
? ? ? ? ? ? ? ? ? try {
? ? ? ? ? ? ? ? ? ? ? ThreadStatusDemo.class.wait();
? ? ? ? ? ? ? ? ? } catch (InterruptedException e) {
? ? ? ? ? ? ? ? ? ? ? e.printStackTrace();
? ? ? ? ? ? ? ? ? }
? ? ? ? ? ? ? }
? ? ? ? ? }
? ? ? ?},"waiting").start();
? ? ? ?new Thread(new BlockDemo(),"BlockDemo-0").start();
? ? ? ?new Thread(new BlockDemo(),"BlockDemo-1").start();
? ?}
? ?static ?class ?BlockDemo extends ?Thread{
? ? ? ?@Override
? ? ? ?public void run() {
? ? ? ? ? ?synchronized ( BlockDemo.class){
? ? ? ? ? ? ? ?try {
? ? ? ? ? ? ? ? ? ?TimeUnit.SECONDS.sleep(100);
? ? ? ? ? ? ? ?} catch (InterruptedException e) {
? ? ? ? ? ? ? ? ? ?e.printStackTrace();
? ? ? ? ? ? ? ?}
? ? ? ? ? ?}
? ? ? ?}
? ?}
}
結(jié)果
E:\lession\target\classes\com\example\lession\thread>jstack 8712
2019-01-20 15:16:20
Full thread dump Java HotSpot(TM) 64-Bit Server VM (25.144-b01 mixed mode):
"DestroyJavaVM" #17 prio=5 os_prio=0 tid=0x00000000025ea000 nid=0xce0 waiting on condition [0x0000000000000000]
? java.lang.Thread.State: RUNNABLE
"BlockDemo-1" #16 prio=5 os_prio=0 tid=0x0000000059c5c800 nid=0x27a8 waiting for monitor entry [0x000000005a5af000]
? java.lang.Thread.State: BLOCKED (on object monitor)
? ? ? ?at com.example.lession.thread.ThreadStatusDemo$BlockDemo.run(ThreadStatusDemo.java:42)
? ? ? ?- waiting to lock <0x00000000d82d41f0> (a java.lang.Class for com.example.lession.thread.ThreadStatusDemo$BlockDemo)
? ? ? ?at java.lang.Thread.run(Thread.java:748)
"BlockDemo-0" #14 prio=5 os_prio=0 tid=0x0000000059c5a000 nid=0xd50 waiting on condition [0x00000000598ff000]
? 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.example.lession.thread.ThreadStatusDemo$BlockDemo.run(ThreadStatusDemo.java:42)
? ? ? ?- locked <0x00000000d82d41f0> (a java.lang.Class for com.example.lession.thread.ThreadStatusDemo$BlockDemo)
? ? ? ?at java.lang.Thread.run(Thread.java:748)
"waiting" #12 prio=5 os_prio=0 tid=0x0000000059c59000 nid=0x24b4 in Object.wait() [0x000000005a49f000]
? java.lang.Thread.State: WAITING (on object monitor)
? ? ? ?at java.lang.Object.wait(Native Method)
? ? ? ?- waiting on <0x00000000d7fc0708> (a java.lang.Class for com.example.lession.thread.ThreadStatusDemo)
? ? ? ?at java.lang.Object.wait(Object.java:502)
? ? ? ?at com.example.lession.thread.ThreadStatusDemo.lambda$main$1(ThreadStatusDemo.java:23)
? ? ? ?- locked <0x00000000d7fc0708> (a java.lang.Class for com.example.lession.thread.ThreadStatusDemo)
? ? ? ?at com.example.lession.thread.ThreadStatusDemo$$Lambda$2/443308702.run(Unknown Source)
? ? ? ?at java.lang.Thread.run(Thread.java:748)
"timewaiting" #11 prio=5 os_prio=0 tid=0x0000000059c55800 nid=0x10d8 waiting on condition [0x000000005a37e000]
? 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.example.lession.thread.ThreadStatusDemo.lambda$main$0(ThreadStatusDemo.java:12)
? ? ? ?at com.example.lession.thread.ThreadStatusDemo$$Lambda$1/205797316.run(Unknown Source)
? ? ? ?at java.lang.Thread.run(Thread.java:748)
"Service Thread" #10 daemon prio=9 os_prio=0 tid=0x0000000058c0a000 nid=0x2134 runnable [0x0000000000000000]
? java.lang.Thread.State: RUNNABLE
"C1 CompilerThread2" #9 daemon prio=9 os_prio=2 tid=0x0000000058b68000 nid=0x1ea4 waiting on condition [0x0000000000000000]
? java.lang.Thread.State: RUNNABLE
"C2 CompilerThread1" #8 daemon prio=9 os_prio=2 tid=0x0000000058b5f800 nid=0x1fac waiting on condition [0x0000000000000000]
? java.lang.Thread.State: RUNNABLE
"C2 CompilerThread0" #7 daemon prio=9 os_prio=2 tid=0x0000000058b5e800 nid=0x2090 waiting on condition [0x0000000000000000]
? java.lang.Thread.State: RUNNABLE
"Monitor Ctrl-Break" #6 daemon prio=5 os_prio=0 tid=0x0000000058b5c000 nid=0x2470 runnable [0x00000000591cf000]
? java.lang.Thread.State: RUNNABLE
? ? ? ?at java.net.SocketInputStream.socketRead0(Native Method)
? ? ? ?at java.net.SocketInputStream.socketRead(SocketInputStream.java:116)
? ? ? ?at java.net.SocketInputStream.read(SocketInputStream.java:171)
? ? ? ?at java.net.SocketInputStream.read(SocketInputStream.java:141)
? ? ? ?at sun.nio.cs.StreamDecoder.readBytes(StreamDecoder.java:284)
? ? ? ?at sun.nio.cs.StreamDecoder.implRead(StreamDecoder.java:326)
? ? ? ?at sun.nio.cs.StreamDecoder.read(StreamDecoder.java:178)
? ? ? ?- locked <0x00000000d8030d18> (a java.io.InputStreamReader)
? ? ? ?at java.io.InputStreamReader.read(InputStreamReader.java:184)
? ? ? ?at java.io.BufferedReader.fill(BufferedReader.java:161)
? ? ? ?at java.io.BufferedReader.readLine(BufferedReader.java:324)
? ? ? ?- locked <0x00000000d8030d18> (a java.io.InputStreamReader)
? ? ? ?at java.io.BufferedReader.readLine(BufferedReader.java:389)
? ? ? ?at com.intellij.rt.execution.application.AppMainV2$1.run(AppMainV2.java:64)
"Attach Listener" #5 daemon prio=5 os_prio=2 tid=0x00000000588fc000 nid=0x274c waiting on condition [0x0000000000000000]
? java.lang.Thread.State: RUNNABLE
"Signal Dispatcher" #4 daemon prio=9 os_prio=2 tid=0x000000005747f000 nid=0x1c88 runnable [0x0000000000000000]
? java.lang.Thread.State: RUNNABLE
"Finalizer" #3 daemon prio=8 os_prio=1 tid=0x000000005745c800 nid=0x20c4 in Object.wait() [0x00000000588de000]
? java.lang.Thread.State: WAITING (on object monitor)
? ? ? ?at java.lang.Object.wait(Native Method)
? ? ? ?- waiting on <0x00000000d7d88ec8> (a java.lang.ref.ReferenceQueue$Lock)
? ? ? ?at java.lang.ref.ReferenceQueue.remove(ReferenceQueue.java:143)
? ? ? ?- locked <0x00000000d7d88ec8> (a java.lang.ref.ReferenceQueue$Lock)
? ? ? ?at java.lang.ref.ReferenceQueue.remove(ReferenceQueue.java:164)
? ? ? ?at java.lang.ref.Finalizer$FinalizerThread.run(Finalizer.java:209)
"Reference Handler" #2 daemon prio=10 os_prio=2 tid=0x0000000057415800 nid=0x16e4 in Object.wait() [0x00000000587ce000]
? java.lang.Thread.State: WAITING (on object monitor)
? ? ? ?at java.lang.Object.wait(Native Method)
? ? ? ?- waiting on <0x00000000d7d86b68> (a java.lang.ref.Reference$Lock)
? ? ? ?at java.lang.Object.wait(Object.java:502)
? ? ? ?at java.lang.ref.Reference.tryHandlePending(Reference.java:191)
? ? ? ?- locked <0x00000000d7d86b68> (a java.lang.ref.Reference$Lock)
? ? ? ?at java.lang.ref.Reference$ReferenceHandler.run(Reference.java:153)
"VM Thread" os_prio=2 tid=0x000000005740e000 nid=0x19d0 runnable
"GC task thread#0 (ParallelGC)" os_prio=0 tid=0x00000000025ff800 nid=0x638 runnable
"GC task thread#1 (ParallelGC)" os_prio=0 tid=0x0000000002601000 nid=0x3a8 runnable
"GC task thread#2 (ParallelGC)" os_prio=0 tid=0x0000000002602800 nid=0x1ca4 runnable
"GC task thread#3 (ParallelGC)" os_prio=0 tid=0x0000000002604800 nid=0x2130 runnable
"VM Periodic Task Thread" os_prio=2 tid=0x0000000058c65800 nid=0x1e44 waiting on condition
JNI global references: 336
------------
再次感謝您已看完全文,歡迎關(guān)注微信公眾號(hào)`猿碼` ,您的關(guān)注我會(huì)持續(xù)更新文章!