Exchanger 实际可以看作一个同步点,两个线程在该同步点能够以线程安全的方式互换数据。如果两个线程的运行速度不同,则运行的较快的线程会被阻塞,直到运行较慢的线程赶到同步点之后,两个线程才可开始交换数据。
如果要在线程间互发多组数据,可以使用blockingQueue接口,特点是:如果队列里没有可用空间,则插入操作会被阻塞,如果队列里没有可用数据,则删除操作会被阻塞。如果想要插入操作和删除一一对应,可以使用SynchronousQueue类,如果希望数据可以根据某种优先级在队列中上下浮动,则可以使用PriorityBlockingQueue。如果只想要一个简单的阻塞队列可以用链表实现的LinkedBlockingQueue或数组方式实现的ArrayBlockingQueue。
ForkJoinPool 类可以根据可用的处理器数量和任务需求动态地对线程进行管理。使用了work-stealing策略,即线程在完成自己的任务以后,发现其他线程还有活没有干完,就主动帮其他人一起干。
ForkJoinTask有两个子类,RecursiveAction和RecursiveTask。RecursiveAction的子类主要用来执行不需要的返回值的任务,而RecursiveTask的子类则主要用于执行需要返回值的任务
fork-join非常适合解决那些可以递归分解至小到足以顺序运行的问题
像Vector这种在Java早期版本中发布的集合类虽然是线程安全的,但却以牺牲部分性能为代价。
一个变量仅能被一个线程访问,该变量为隔离的且非共享的
千万不要在构造函数里启动线程,可以考虑用静态工厂函数来代替构造函数初始化
例如:
private Demo(){}
private void init(){
new Thread(new Runnable()){
public void run(){
//要执行的任务
}
}
}
public static Demo create(){
final Demo demo = new Demo();
demo.init();
return demo;
}
确保对可变字段的访问跨越内存栅栏,并对线程可见