了解线程由来
单核CPU之所以能够实现多进程,主要是依赖操作系统的进程调度算法。如时间片轮转算法,可以实现QQ、微信、浏览器同时运行,从而实现多进程。
随着计算机技术的发展,进程出现很多弊端,一是由于进程是资源拥有者,创建、撤消与切换存在较大的时空开销,因此需要引入轻量进程; 二是由于对称多处理机出现,可以满足多个运行单位,而多个进程并行开销过大。
因此在80年代,出现了能独立运行的基本单位 --- 线程。
从单核到多核
最初计算机是单任务的,然后发展到多任务,接着出现多线程并行,同时计算机也从单cpu进入到多cpu。如下图
多任务:其实就是利用操作系统时间片轮转使用的原理。操作系统通过将cpu的执行时间分割成多个时间片,为每个任务分配时间片,因为cpu处理速度很快,这样就用户看来好像每个任务都在同时执行,感觉有多个cpu,但本质上一个时间点只有一个任务在运行。
为什么会有线程?
线程切换比进程切换速度会快
在什么场景下使用多线程?
- 通过并行计算提高程序性能
- 等待网络、IO响应导致的耗时时间问题
线程的分类有哪些?
用户线程、内核线程、混合式
进程和线程的关系?
根本区别:进程是资源分配的最小单位,线程是CPU调度的最小单位
进程是一个应用程序在处理机上的一次执行过程,它是一个动态概念,而线程是进程中的一部分,进程包含多个线程在运行。
开销:每个进程都有独立的代码和数据空间,程序之间的切换会有较大的开销;线程可以看做轻量级的进程,同一类线程共享代码和数据空间,每个线程都有自己独立的运行栈和程序计数器,线程之间切换的开销小。
内存分配:系统在运行的时候会为每个进程分配不同的内存空间,则线程除了CPU之外,系统不会为线程分配内存,线程组之是只能共享资源。
线程的实现方法有哪些
Thread、Runnable、Callable/future
线程的状态有哪些
NEW 新建
READY 就绪
RUNNABLE 运行
BLOCKED 阻塞
等待阻塞 wait
同步阻塞 synchronized
其他阻塞 sleep/join
WAITING 等待
TIMED_WAITING 超时等待
TERMINATED 终止
线程状态图如下:
查看线程状态的代码如下:
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(); } } } } }
结果
E:lession argetclassescomexamplelession hread>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
------------
欢迎关注微信公众号 “零售云技术”,文章持续更新