了解线程由来
单核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\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
------------
再次感谢您已看完全文,欢迎关注微信公众号`猿码` ,您的关注我会持续更新文章!