JUC 是什么
java.util.concurrent 在并发编程中使用的工具包
从线程start 开始
package com.jhj.Thread;
public class ThreadDemo {
public static void main(String[] args) {
Thread t1 = new Thread(() -> {
}, "t1");
t1.start();
}
}
start 方法调的是native start0 本地方法 本地方法用C++ 实现。 实际上由jvm 配合操作系统起的
执行 openjdk8\jsk\sec\share\native\java\lang thread.c 与Thread.java 对应
openjdk8\jsk\sec\share\vm\prims jvm.cpp 线程start
openjdk8\jsk\sec\share\vm\runtime thread.cpp 464 行 操作系统start
多线程相关概念
- 一把锁 synchronized
- 两个并 并发(concurrenr)与并行(parallel)
并发是同一实体上的多个事件,是在一台处理器上“同时"处理多个任务,同一时刻,其实是只有一个事件在发生。
并行是在不同实体上的多个事件,是在多台处理器上同时处理多个任务,同一时刻,大家真的都在做事情,你做你的,我做我的。
并发vs并行 - 三个程 进程线程管程
进程是系统内运行的一个应用程序,每一个进程都有它自己的内存空间和系统资源。每一个进程有很多个线程。
线程被称为轻量级的进程,在同一个进程内会有一个或者多个线程,是大多数操作系统进行时序调度的基本单元。
管程 Monitor(监视器) 也就是我们平时说的锁,每一个对象都有minitor对象,底层用c++实现执行线程需要先成功持有管程,谁抢到锁就持有管程,才能执行,执行完成释放管程。相当于锁
用户线程和守护线程
java 线程分为用户线程和守护线程 默认都是用户线程,整个系统默认良好运作,会提供一个守护线程。
- 用户线程,系统的工作线程,他会完成这个程序需要完成的业务操作。
- 守护线程,是一种特殊的线程为其他线程服务的,在后台默默地完成一些系统性地服务,比如垃圾回收线程就是最典型地例子。作为一个服务线程,没有服务对象就没有必要继续运行了,如果用户线程全部结束了,意味着程序需要完成的业务操作已经结束了,系统可以退出了,当系统只剩下守护线程时,java 虚拟机会自动退出。
线程Daemon
判断线程是否时守护线程
/**
* Tests if this thread is a daemon thread.
*
* @return <code>true</code> if this thread is a daemon thread;
* <code>false</code> otherwise.
* @see #setDaemon(boolean)
*/
public final boolean isDaemon() {
return daemon;
}
package com.jhj.Thread;
import java.util.concurrent.TimeUnit;
public class ThreadDemo {
public static void main(String[] args) {
Thread t1 = new Thread(() -> {
System.out.println(Thread.currentThread().getName()+"是守护"+Thread.currentThread().isDaemon());
while (true){
}
}, "t1");
t1.start();
try {
TimeUnit.SECONDS.sleep(3);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("结束");
}
}
默认都是用户线程,两个线程执行
package com.jhj.Thread;
import java.util.concurrent.TimeUnit;
public class ThreadDemo {
public static void main(String[] args) {
Thread t1 = new Thread(() -> {
System.out.println(Thread.currentThread().getName()+"是守护"+Thread.currentThread().isDaemon());
while (true){
}
}, "t1");
t1.setDaemon(true);
t1.start();
try {
TimeUnit.SECONDS.sleep(3);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("结束");
}
}
设置为守护线程后,用户线程结束 守护线程随着关闭,如果用户线程全部结束意味着程序需要完成的业务操作已经结束了,守护线程随着JVM一同结束工作。 t1.setDaemon(true);必须在start 之前设置,否则会发生线程不合法异常
作者声明
如有问题,欢迎指正!