JUC大家可能听说过,它实际上 Java 提供的用于并发处理的工具包。如官方文档所示:
回顾以前
在以前的业务中,我们使用的代码:
1、Thread
2、Runnable:没有返回值、无法抛出异常、效率相比 Callable 较低!
3、Callable
4、还有Locked锁
这些以前多多少少都有接触过。
开发环境的配置
- 该分类的所有的测试代码都会在该工程下进行。
1、创建一个Maven项目
2、导入lombok插件
<dependencies> <dependency> <groupId>org.projectlombok</groupId> <artifactId>lombok</artifactId> <version>1.18.8</version> </dependency> </dependencies>
3、使用JDK1.8
4、应用 lambda,需要配置3处
- 第一处
- 第二处
- 第三处
线程和进程、并发和并行
线程和进程
解释
如果不能用一句话概括,可以说是掌握的不扎实。
进程:
- 是指系统中正在运行的一个应用程序,比如:QQ.exe,Music.exe都是程序,这些程序一旦运行都是就是进程。
- 进程是程序的一个集合。
- 一个进程包含多个线程。
线程:
- 什么是线程?举例栗子:比如打开一个 Typora 文本编辑器,其中写字(是一个负责输入的线程),过一段时间自动保存(是一个负责保存的线程)
Java可以开启线程?
对于 Java 而言,Thread,Runnable,Callable都可以开启线程。
重点:但是 Java 真的可以开启线程吗?不可以
为什么呢?因为:
- Java 是运行在虚拟机上的,无法直接操作硬件,所以说 Java 没有开启线程的权限,它只是调用了底层的c++
接下来通过 Java 创建一个线程,来查看源码。
点进去这个 start() 方法
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 */ } } } // native:本地方法, c++ private native void start0();
1、
2、调用 start0()
方法启动线程。
3、
线程有几种状态?
答案:6种,新生、运行、阻塞、等待、超时等待、终止;
- 在 Thread 线程定义了一个 State 枚举类,它定义了线程的所有状态。
- Thread.State
public enum State { //新生 new NEW, //运行 runnable RUNNABLE, // 阻塞 blocked BLOCKED, // 等待,死死地等 waiting WAITING, // 超时等待 timed_waiting TIMED_WAITING, // 终止 terminated TERMINATED; }
wait 和 sleep的区别
1、来自不同的类
wait => Object
sleep => Thread
- 关于 sleep 的用法,在
java.util.concurrent
包下有一个TimeUnit
类 -
import java.util.concurrent.TimeUnit; public class ThreadTest { public static void main(String[] args) throws InterruptedException { TimeUnit.DAYS.sleep(1); //睡一天 TimeUnit.SECONDS.sleep(1); //睡一秒 } }
2、关于锁的释放
wait:会释放锁;sleep:不会释放锁。
可以理解成sleep是抱着锁睡觉的,wait没有抱着锁
并发和并行
解析
并发:是多个线程共用同一份资源
- 在 CPU 只有一核的情况下,怎么才能做到并发操作?
- 天下武功唯快不破,快速的交替运行就可以达到多线程的效果。
并行:是多个人一起行走
- 在 CPU 多核的情况下,多个线程可以同时执行,可以利用线程池进行开发。
如何查看CPU的逻辑处理器(表示可以同时开启的线程个数)
1、通过任务管理器
2、桌面 -> 此电脑 -> 右击管理 -> 设备管理器 -> 点击右边窗口的处理器
3、程序员方式查看,通过代码
public class ThreadTest { public static void main(String[] args) { System.out.println(Runtime.getRuntime().availableProcessors()); } }
并发编程的本质
充分利用 CPU 资源,在现在的二进制环境下,谁能充分利用CPU的资源,就可以有成果。