并发经验
1.保持可运行线程数量尽可能的少的主要技术是,让每个线程做少量的工作,然后使用Object.wait等待某个条件发生,或者使用Thread.sleep()睡眠一段时间,线程不应该忙-等busy-wait,即反复的检查一个数据结构,以等待某些事件发生。除了使程序易受调度器的变化的影响外,忙等这种做法还会增加处理器的负担.
2.永远不要在循环外面调用wait .
wait的标准模式:
synchronized(obj){
while(<condition does not hold>)
obj.wait();
...//perform action appropriate to condition
}
3.interrupt()不会中断正在执行的线程,只是将线程的标志位设置成true。但是如果线程在调用sleep(),join(),wait()方法时线程被中断,则这些方法会抛出InterruptedException,在catch块中捕获到这个异常时,线程的中断标志位已经被设置成false了,因此在此catch块中调用t.isInterrupted(),Thread.interrupted()始终都为false,
而t.isInterrupted与Thread.interrupted()的区别是API中已经说明很明显了,Thread.interrupted()假如当前的中断标志为true,则调完后会将中断标志位设置成false
--------------------------------------------------------------------
以上为今天看的前辈们并发相关的博文,仔细分析后摘录下来的经验之谈。
补充:
busy-wait模式:
while(true){
if(A&&B){
System.out.println("busy...waiting");
}
System.out.println("end...busy");
}
但有时候,busy-wait模式也有适用的时候,比如Java自旋锁在线程竞争锁时的“自旋机制”,还有在jdk1.5以后提供的java.util.concurrent.atomic包,该包里面提供了一组原子类,该原子类也有对busy-wait模式的使用,
比如,AtomicBoolean:
(jdk1.8源码,其他版本或许有不同之处)
public final boolean getAndSet(boolean newValue) {
boolean prev;
do {
prev = get();
} while (!compareAndSet(prev, newValue));
return prev;
}
此处,使用(!compareAndSet(prev, newValue))来控制busy-wait模式.