@@ -54,15 +54,15 @@ Linux系统会给每个进程分配4G的虚拟地址空间(0到3G是User地址
5454
5555五态模型一般指的是:
5656
57- 新建态(创建一个进程)
57+ ** 新建态** (创建一个进程)
5858
59- 就绪态(已经获取到资源,准备好了,进入运行队列,一旦获得时间片可以立即执行)
59+ ** 就绪态** (已经获取到资源,准备好了,进入运行队列,一旦获得时间片可以立即执行)
6060
61- 运行态(获取到了时间片,执行程序)
61+ ** 运行态** (获取到了时间片,执行程序)
6262
63- 阻塞态(运行过程中等待获取其他资源,I/O请求等)
63+ ** 阻塞态** (运行过程中等待获取其他资源,I/O请求等)
6464
65- 终止态(进程被杀死了)
65+ ** 终止态** (进程被杀死了)
6666
6767#### 并发性
6868
@@ -204,7 +204,7 @@ class ThreadTarget implements Runnable {
204204
205205##### 原理
206206
207- 之所以有这种实现方法,是因为Thread类的run方法中会判断成员变量target是否为空 ,不为空就会调用target类的run方法。
207+ 之所以有这种实现方法,是因为Thread类的run()方法中会判断成员变量target是否为空 ,不为空就会调用target类的run方法。
208208
209209``` java
210210private Runnable target;
@@ -258,7 +258,7 @@ thread.start()
258258
259259#### 第三种 实现Callable接口
260260
261- Runnable接口中的run方法是没有返回值 ,如果我们需要执行的任务带返回值就不能使用Runnable接口。创建一个类CallableTarget,实现Callable接口,实现带有** 返回值的call()方法** ,然后根据CallableTarget创建一个任务FutureTask,然后根据FutureTask来创建一个线程Thread,调用Thread的start方法可以执行任务。
261+ Runnable接口中的run()方法是没有返回值 ,如果我们需要执行的任务带返回值就不能使用Runnable接口。创建一个类CallableTarget,实现Callable接口,实现带有** 返回值的call()方法** ,然后根据CallableTarget创建一个任务FutureTask,然后根据FutureTask来创建一个线程Thread,调用Thread的start方法可以执行任务。
262262
263263``` java
264264public class CallableTarget implements Callable<Integer > {
@@ -386,6 +386,40 @@ public interface RunnableFuture<V> extends Runnable, Future<V> {
386386}
387387```
388388
389+ ##### 使用案例
390+
391+ 使用时,Runnable实现类的实例可以作为Thread的入参使用,而Callable只能使用FutureTask进行封装使用。
392+
393+ ``` java
394+ // Runnable配合Thread进行使用
395+ Thread threadA = new Thread (new Runnable () {
396+ @Override
397+ public void run () {
398+ // 任务的代码
399+ }
400+ });
401+
402+ // Callable使用FutureTask封装后,配合线程池进行使用
403+ ExecutorService pool = Executors . newSingleThreadExecutor();
404+ FutureTask task = new FutureTask (new Callable () {
405+ @Override
406+ public Object call () throws Exception {
407+ // 任务的代码
408+ return null ;
409+ }
410+ });
411+ pool. submit(task);
412+
413+ // Runnable使用FutureTask封装后,配合线程池进行使用
414+ FutureTask task1 = new FutureTask (new Runnable () {
415+ @Override
416+ public void run () {
417+ // 任务的代码
418+ }
419+ });
420+ pool. submit(task1);
421+ ```
422+
389423### Java中单例有哪些写法?
390424
391425正确并且可以做到延迟加载的写法其实就是三种:
@@ -762,14 +796,11 @@ static void ensure_join(JavaThread* thread) {
762796
763797 thread- > clear_pending_exception();
764798
765- java_lang_Thread:: set_thread_status(threadObj(), java_lang_Thread:: TERMINATED );
766-
799+ java_lang_Thread:: set_thread_status(threadObj(), java_lang_Thread:: TERMINATED );
767800 java_lang_Thread:: set_thread(threadObj(), NULL );
768-
769801 // 同志们看到了没,别的不用看,就看这一句
770802 // thread就是当前线程,是啥?就是刚才例子中说的threadA线程
771803 lock. notify_all(thread);
772-
773804 thread- > clear_pending_exception();
774805}
775806```
@@ -848,24 +879,24 @@ FutureTask提供了cancel(boolean mayInterruptIfRunning)方法来取消任务,
848879示例代码如下:
849880
850881``` java
851- Thread threadA = new Thread (new Runnable () {
852- @Override
853- public void run () {
882+ Thread threadA = new Thread (new Runnable () {
883+ @Override
884+ public void run () {
854885 // 执行threadA的任务
855- }
856- });
857- Thread threadB= new Thread (new Runnable () {
858- @Override
859- public void run () {
860- // 执行threadB的任务
861- }
862- });
863- // 执行线程A任务
864- threadA. start();
865- // 主线程进行等待
866- threadA. join();
867- // 执行线程B的任务
868- threadB. start();
886+ }
887+ });
888+ Thread threadB= new Thread (new Runnable () {
889+ @Override
890+ public void run () {
891+ // 执行threadB的任务
892+ }
893+ });
894+ // 执行线程A任务
895+ threadA. start();
896+ // 主线程进行等待
897+ threadA. join();
898+ // 执行线程B的任务
899+ threadB. start();
869900```
870901
871902##### 子线程Join
@@ -1422,9 +1453,9 @@ public ThreadPoolExecutor(int corePoolSize,
14221453
14231454从阻塞队列取任务时,如果阻塞队列为空:
14241455
1425- 核心线程的会一直卡在 `workQueue. take`方法,被阻塞并挂起,不会占用CPU 资源。
1456+ ** 核心线程 ** 的会一直卡在 `workQueue. take`方法,被阻塞并挂起,不会占用CPU 资源。
14261457
1427- 非核心线程会调用workQueue . poll(keepAliveTime, TimeUnit . NANOSECONDS )方法取任务 ,如果超过keepAliveTime时间后还没有拿到,下一次循环判断** compareAndDecrementWorkerCount** 就会返回`null `,Worker 对象的`run()`方法循环体的判断为`null `,任务结束,然后线程被系统回收)
1458+ ** 非核心线程 ** 会调用workQueue . poll(keepAliveTime, TimeUnit . NANOSECONDS )方法取任务 ,如果超过keepAliveTime时间后还没有拿到,下一次循环判断** compareAndDecrementWorkerCount** 就会返回`null `,Worker 对象的`run()`方法循环体的判断为`null `,任务结束,然后线程被系统回收)
14281459
14291460##### 2. maximumPoolSize 最大线程数
14301461
@@ -1611,8 +1642,6 @@ ThreadPoolExecutor提供了如下几个public的setter方法
16111642
16121643! [image- 20210119104549770 ](.. / static / image- 20210119104549770. png)
16131644
1614-
1615-
16161645调用corePoolSize方法之后,线程池会直接覆盖原来的corePoolSize值,并且基于当前值和原始值的比较结果采取不同的处理策略。(总得来说就是,多退少补的策略)
16171646
16181647** 对于新corePoolSize< 当前工作线程数的情况:**
0 commit comments