JUC是java.util.concurrent包的缩写,是java并发包。
java.util 工具包
业务:普通的线程代码 Thread
Runnable 没有返回值,效率相比于Callable相对较低!
1.2、进程、线程
进程:一个程序,QQ.exe Music.exe 程序的集合。
一个进程可以包含多个线程,至少包含一个!
java默认有有几个线程? 2个 main线程、GC
线程:开了一个进程Typora,写字,自动保存(线程负责的)
对于java而言:Thread、Runnable、Callable
java真的可以开启线程码?
public synchronized void start() {
/**
* This method is not invoked for the main method thread or "system"
* group threads created/set up by the VM. Any new functionality added
* to this method in the future may have to also be added to the VM.
*
* A zero status value corresponds to state "NEW".
*/
if (threadStatus != 0)
throw new IllegalThreadStateException();
/* Notify the group that this thread is about to be started
* so that it can be added to the group's list of threads
* and the group's unstarted count can be decremented. */
group.add(this);
boolean started = false;
try {
start0();
started = true;
} finally {
try {
if (!started) {
group.threadStartFailed(this);
}
} catch (Throwable ignore) {
/* do nothing. If start0 threw a Throwable then
it will be passed up the call stack */
}
}
}
// 本地方法,底层的c++ java无法直接操作硬件
private native void start0();
1.3、并发、并行
并发编程:并发、并行
开发(多线程操作同一个资源)
- CPU 一核 ,模拟出多条线程,天下武功,唯快不破,快速交替
并行(多个人一起行走)
- CPU 多核,多个线程可以同时执行:线程池
public class Test1 {
public static void main(String[] args) {
// 获取CPU的核数
// CPU密集型、IO密集型
System.out.println(Runtime.getRuntime().availableProcessors());
}
}
并发编程的本质:充分利用CPU的资源
1.4、线程有几个状态
public enum State {
// 新建
NEW,
// 运行
RUNNABLE,
// 阻塞
BLOCKED,
// 等待,死死地等
WAITING,
// 超时等待,过期不候
TIMED_WAITING,
// 终止
TERMINATED;
}
注
:java定义了6个状态,操作系统层面是5个
1.5、wait/sleep区别
1、来自不同的类
wait -> Object
sleep -> Thread
补充:
企业里睡眠一般不用Sleep,一般用一个工具类:
TimeUnit.DAYS.sleep(1); // 睡一天
TimeUnit.SECONDS.sleep(2); // 睡两秒
2、关键字的释放
sleep()方法不会释放锁,所以其他线程无法访问它的锁对象,就相当于一个工人进一个厂房后,带着门口的钥匙进去后,在里面睡觉了,这时因为钥匙被它带进去,别人是进不去这个厂房的,并且它醒来后不会立即执行,也是需要cpu的调度,但是它不需要去竞争锁,因为锁就在他手里,只有等它使用完毕后或者中断线程(interrup())才会释放锁
wait()方法会立即释放锁,就相当于是一个工人进去厂房后,由于一些原因,需要别人处理一些东西后才能处理,他就出来把钥匙挂门上,去门口旁边(等待队列)等着了,这时别人就可以拿着钥匙进去进行处理,处理好了之后再去用notify唤醒它,如果唤醒了多个,如果它没有抢到钥匙,会继续等待
notifyAll() 调用后,会将全部线程由等待池移到锁池,然后参与锁的竞争,竞争成功则继续执行,如果不成功则留在锁池等待锁被释放后再次参与竞争。而 notify()只会唤醒一个线程,具体唤醒哪一个线程由虚拟机控制。
3、使用的范围是不同
sleep可以再任何地方使用
wait必须再同步代码块中
4、是否捕获异常
wati 不需要捕获异常
sleep必须捕获异常