并发概念汇总
http://www.letiantian.me/2015-05-27-java-concurrency-summary/
并发的系统文章
http://www.cnblogs.com/dolphin0520/category/602384.html
http://www.cnblogs.com/timlearn/tag/Java%E5%B9%B6%E5%8F%91/
http://blog.csdn.net/ghsau/article/category/1707779
最简单的java线程池与任务队列
http://www.cnblogs.com/null7/archive/2012/09/20/2696108.html
中断机制
http://www.cnblogs.com/timlearn/p/4008783.html
一.运行一个线程
运行一个线程的方法十分简单,我们只需调用Thread实例的start()方法即可,当我们调用start()方法之后,Java虚拟机会为我们创建一个线程,然后在该线程中运行run()方法中定义的任务,真正实现多线程。
在这里,必须强调的是应该调用start()方法,而不是run()方法,直接调用run()方法,虚拟机不会新建线程运行任务,只会在当前线程执行任务,无法实现多线程并发,所以应该调用start()方法。
二.停止一个线程
(1)标志位方法
在任务中定义一个标志位,然后任务会定期查看标志位,如果设置了标志位,则任务结束。注意,标志位必要设置为volatile类型。
我们使用这项技术来枚举素数。
public class PrimeGenerator implements Runnable {
private final List<BigInteger> primes = new ArrayList<BigInteger>();
private volatile boolean cancelled;
public void run() {
BigInteger p = BigInteger.ONE;
while (!cancelled) {
p = p.nextProbablePrime();
synchronized (this) {
primes.add(p);
}
}
}
public void cancel() {
cancelled = true;
}
public synchronized List<BigInteger> get() {
return new ArrayList<BigInteger>(primes);
}
}
当cancel()方法调用后,while就会结束,整个线程也会结束。
(2)使用中断停止线程
在(1)中的使用标志位的方法中,有一个问题,如果线程的任务是阻塞任务,那么线程在阻塞时将无法去查看标志位,因此也无法停止。
当出现这种情况时,我们可以使用中断,有部分阻塞库方法是支持中断的,线程中断是一个协作机制,线程可以通过这种机制来通知另一个线程,告诉它在合适或者可能的情况下停止当前的工作,
并转而执行其它的工作。
修改上面的ArrayList为BlockingQueue,BlockingQueue的put()是可以阻塞的,如果还使用标志位的方法,那么当put阻塞后,将无法再执行while判断,这时我们就可以使用中断标志位的方法来判断结束线程。,
public class PrimeProducer extends Thread {
private final BlockingQueue<BigInteger> queue;
PrimeProducer(BlockingQueue<BigInteger> queue) {
this.queue = queue;
}
public void run() {
try {
BigInteger p = BigInteger.ONE;
while (!Thread.currentThread().isInterrupted())
queue.put(p = p.nextProbablePrime());
} catch (InterruptedException consumed) {
/* Allow thread to exit */
}
}
public void cancel() {
interrupt();//Thread.interrupt()
}
}
这时,我们注意到,cancel()调用时,设置了当前线程的中断标志位为true,BlockingQueue的put()方法可以响应中断,并从阻塞状态返回,返回后,while语句检测到中断位被标志,然后结束整个while
循环,从而结束线程。
(3)不能响应中断的阻塞方法
如果阻塞方法可以响应中断,我们就可以使用(2)中的方法结束线程,但是还有一些阻塞方法不能响应中断。这里就要通过关闭底层资源,让代码throw异常的方式来结束线程。(略)