java 7并发手册_JAVA7并发编程实战手册笔记

第一章  线程管理

​Thread保存的一些属性:

ID

name

priority(1

~ 10)

status​​(new,

runnable, blocked, waiting, time waiting,

terminated)

中断相关:​​

interrupt可以停止线程,但不是预期的结果;​

​interruptisInterrupted(),

interrupted()用来判断线程是否中断,前者不能改变interrupted属性的值,后者能设其为false。

join的用法:

​线程1中调用线程2的join,需要等线程2执行完成,线程1才能完成。

thread2.join(1000)​:线程2执行完成或者1000ms之后,thread1解除挂起。

常驻进程:

setDaemon()方法只能在start()方法被调用之前设置。一旦线程开始运行,将不能再修改守护状态。​​

线程局部变量:P27例子

ThreadLocal startDate =

new​ThreadLocal();解决线程共享问题。​

线程分组:

ThreadGroup​

group =

newThreadGroup(“search”);创建线程组

Thread t​​est

= new Thread(group, runnable);创建线程到线程组

threadGroup.activeCount()获取线程组中包含的线程数目。

​threadGroup.enumerate()获取线程组包含的线程列表。

threadGroup.interrupt()中断线程组中的线程。​

第二章 线程同步基础

使用​synchronized、wait和notify实现生产者消费者同步

​synchronized关键字用来同步对象、方法或者代码块

wait()线程挂起

notify()和notifyAll()唤醒挂起的线程​

​使用Lock锁实现生产者消费者同步

​synchronized只能在同一个快结构中获取和释放控制,Lock允许实现更比synchronized复杂的临界区结构。Lock接口拥有更好的性能。

Lock的用法

private final ​Lock queueLock =

new Reent​rantLock();

​queueLock.lock();

待控制同步代码模块

​queueLock.unlock();

读写锁

锁机制​最大的改进之一就是ReadWriteLock接口和它的唯一实现类ReentrantReadWriteLock。这个类有两个锁,一个是读操作锁,另一个是写操作锁。使用读操作锁时可以允许多个线程同时访问,但是不可进行修改操作;而使用写操作锁时只允许一个线程进行。在一个线程执行写操作时,其他线程不能够执行读操作。​

锁的公平性

​ReentrantReadWriteLock(Boolean

isFair)构造函数有个布尔型入参表示是否公平,true公平,从等待的线程里面选择一个等待最长的运行。false非公平,则下个从等待的线程里面随机选择一个执行。

在锁中使用多条件​

​ReentrantLocklock

= newReentrantLock();

Con​​dition

lines = lock.newCondition();

Con​​dition

space= lock.newCondition();​

lock.lock();

​// 生产者模块​

lines​.await();

space.signalAll();

​// 消费者模块

​space.await();

lines.signalAll();

​lock.unlock();

第五章

Fork/Join框架

1、创建Fork / Join线程池

ForkJoinPool 的用法:

ForkJoinPool pool = new ForkJoinPool();

pool.execute(task);

do{

......

}while(!task.isDone)

pool.shutdown();

public class Task extends RecursiveAction{

......

}

compute方法,实现任务的执行逻辑。

2、合并任务的结果 P179

RecursiveTask的用法:

public class DocumentTask extends

RecursiveTask{

...

}

RecursiveTask task = new RecursiveTask(......);

task 的compute中执行分治:

RecursiveTask task1 = new

RecursiveTask(......);

RecursiveTask task2 = new

RecursiveTask(......);

invokeAll(task1, task2);

result = grouResults(task1.get(), task2.get());

return result;

pool.execute(task);

...

pool.shutdown();

pool.awaitTermination(1, TimeUnit.DAYS);

print(task.get());

3、异步运行任务

3.1 运行任务:​

采用同步方式,例如使用invokeAll()方法时,发送任务给Fork/Join线程池的方法直到任务执行完成后才返回结果。

相反,当采用异步方法(比如fork)时,任务将继续执行,因此ForkJoinPool类无法​使用工作窃取算法来提升应用程序的性能。只有调用join()、get()方法来等待任务的结束时,ForkJoinPool类才可以使用工作窃取算法; join​()方法在主任务中被调用,然后等待任务执行结束,并通过comute()方法返回值。

3.2 取消任务

task.cancel(isTrue)​

cancel方法允许取消一个仍没有执行的任务,这是非常重要的。如果任务已经开始执行,那么调用cancel()方法也无法取消。

如果传递true,即使任务正在执行也将被取消。

遗留问题:

​RecursiveAction

和RecursiveTask的区别?

Re:

RecursiveAction用于任务没有返回结果的场景。

RecursiveTask​用于任务有返回结果的场景。

我们的目标是边开发变成长,早日成为一名​卓越的工程师,而不仅仅只是像劳役一样地不停地为完成任务和做任务。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值