本章内容:
* 什么是线程
* 中断线程
* 线程状态
* 线程属性
* 同步
* 阻塞队列
* 线程安全的集合
* Collable与Future
* 执行器
* 同步器
* 线程与Swing

t.setDaemon(true) 将线程转换为守护线程( daemon thread )。守护线程的唯一用途是为其他线程提供服务。计时线程就是一个例子,它定时地发送“计时器嘀嗒”信号给其他线程或清空过时的高速缓存项的线程。当只剩下守护线程时,虚拟机就退出了,由于如果只剩下守护线程,就没必要继续运行程序了。 void uncaughtException(Thread t,Throwable e)
 myLock.lock(); //a ReentrantLock object
 try
 {
     critical section
 }
 finally
 {
     myLock.unlock();//make sure the lock is unlocked even if an exception is three
 }
 while(!(ok to proceed))
     condition.await();
 intrinsicCondition.await();
 intrinsicCondition.signalAll();
 synchronized(obj) //this is the     synchronized block
 {
     critical section
 }
private volatile boolean done;
public void flipDone(){done = !done;} //not atomic
 final Map<String,Double> accounts = new HashMap();
 public static final ThreadLocal< SimpleDateFormat > dateFormat = new ThreadLocal< SimpleDateFomrat >()
 {
     protected SimpleDateFormat initialValue()
     {
         return new SimpleDateFormat("yyyy-MM-dd");
     }
 }
 String dateStamp = dateFormat.get().format(new Date());
 int random = ThreadLocalRandom.current().nextInt(upperBound);
 myCondition.await(100,TimeUnit.MILLISECONDS)
 private ReentrantReadWriteLock rwl = new ReentrantReadWriteLock();
 private Lock readLock = rwl.readLock();
 private Lock writeLock = rwl.writeLock();
 public double getTotalBalance()
 {
     readLock.lock();
     try{...}
     finally{readLock.unlock();}
 }
 public void transfer(...)
 {
     writeLock.lock();
     try{...}
     finally{writeLock.unlock();}
 }
| 方法 | 正常动作 | 特殊情况下的动作 | 
|---|---|---|
| add | 添加一个元素 | 如果队列满,则抛出IllegalStateException异常 | 
| element | 返回队列的头元素 | 如果队列空,抛出NoSuchElementException异常 | 
| offer | 添加一个元素并返回true | 如果队列满,返回false | 
| peek | 返回队列的头元素 | 如果队列空,则返回null | 
| poll | 移出并返回队列的头元素 | 如果队列空,则返回null | 
| put | 添加一个元素 | 如果队列满,则阻塞 | 
| remove | 移出并返回头元素 | 如果队列空,则抛出NoSuchElementException异常 | 
| take | 移出并返回头元素 | 如果队列空,则阻塞 | 
 boolean success = q.offer(x,100,TimeUnit.MILLISECONDS);
 Object head = q.poll(100,TimeUnit.MILLISEDS);
 interface Delayed extends Comparable< Delayed >
 {
     long getDelay(TimeUnit unit);
 }
q.transfer(item);
 cache.putIfAbsent(key,value);
 cache.remove(key,value);
cache.replace(key,oldValue,newValue);
 List< E > synchArrayList = Collections.synchronizedList(new ArrayList< E >());
 Map< K,V > synchHashMap = Collections.synchronizedMap(new HashMap< K,V >());
 synchronized(synchHashMap)
 {
     Iterator< K > iter = synchHashMap.keySet().iterator();
     while(iter.hashNext())...;
 }
 public interface Callable< V >
 {
     V call() throws Exception;
 }
 public interface Future< V >
 {
     V get() thros ...;
     V get(long timeout,TimeUnit unit) throwa...;
     void cancel(boolean mayInterupt);
     boolean isCancelled();
        boolean isDone();
}
| 方法 | 描述 | 
|---|---|
| newCachedThreadPool | 必要时创建新线程;空闲线程会被保留60秒 | 
| newFixedThreadPool | 该池包含固定数量的线程;空闲线程会一直被保留 | 
| newSingleThreadExecutor | 只有一个线程的“池”,该线程顺序执行每一个提交的任务(类似于Swing事件分配线程) | 
| newScheduledThreadPool | 用于预定执行而构建的固定线程池,替代java.util.Timer | 
| newSingleThreadScheduleExecutor | 用于预定执行而构建的单线程“池” | 
 Future<?> submit(Runnable task)
 Future< T > submit(Runnable task,T result)
 Future< T > submit(Callable< T > task)
 List<Callable< T >> tasks=...;
 List<Future< T >> results =             executor.invokeAll(tasks);
 for (Future< T > result:results)
     processFurther(result.get());
 ExecutorCompletionService service = new ExecutorCompletionService(executor);
 for(Callable< T > task:tasks) service.submit(task);
 for (int i=0;i<task.size();i++)
     processFurther(service.task().get());
 if(problemSize > threshold)
     solve problem direckly
 else
 {
     break problem into subproblems
     recursively solve each subproblem
     combine the results
 }
| 类 | 它能做什么 | 何时使用 | 
|---|---|---|
| CyclicBarrier | 允许线程集等待直至其中预定数目的线程到达一个公共障栅(barrier),然后可以选择执行一个处理障栅的动作 | 当大量的线程需要在它们的结果可用之前完成时 | 
| CountDownLatch | 允许线程集等待直到计数器减为0 | 当一个或多个线程需要等待直到指定数目的事件发生 | 
| Exchanger | 允许两个线程在要交换的对象准备好时交换对象 | 当两个线程工作在同一个数据结构的两个实例上的时候,一个向实例添加数据而另一个从实例清除数据 | 
| Semaphore | 允许线程集等待直到被允许继续运行为止 | 限制访问资源的线程总数。如果许可数是1,常常阻塞线程直到另一个线程给出许可为止 | 
| SynchronoutQueue | 允许一个线程把对象交给另一个线程 | 在没有显式同步的情况下,当两个线程准备好将一个对象从一个线程传递到另一个时 | 
将线程与 Swing 一起使用时,必须遵循两个简单的原则。
  制定第一条规则的理由易于理解。如果花很多时间在事件分配线程上,应用程序像“死了”一样,因为它不响应任何事件。特别是,事件分配线程应该永远不要进行 input/output 调用,这有可能会阻塞,并且永远不要调用 sleep 。(如果需要等待指定的时间,使用定时器事件。)
  第二条规则在 Swing 编程中通常称为单一线程规则( single-thread rule )。
  这两条规则看起来彼此冲突。假定要启动一个独立的线程运行一个耗时的任务。线程工作的时候,通常要灯芯用户界面中指示执行的进度。任务完成的时候,要再一次更新 GUI 界面。但是,不能从自己的线程接触 Swing 组件。例如,如果要更新进度条或标签文本,不能从线程中设置它的值。
  要解决这一问题,在任何线程中,可以使用两种有效的方法向事件队列添加任意的动作。例如,假定想在一个线程中周期性地更新标签来表明进度。不可以从自己的线程中调用 label.setText ,而应该使用 EventQueue 类的 invokeLater 方法和 invokeAndWait 方法使所调用的方法在事件分配线程中执行。
  应该将 Swing 代码放置到实现 Runnable 接口的类的 run 方法中。然后,创建该类的一个对象,将其传递给静态的 invokeLater 或 invokeAndWait 方法。
  当事件放入事件队列时, invokeLater 方法立即返回,而 run 方法被异步执行。 invokeAndWait 方法等待直到 run 方法确实被执行过为止。
  有更新进度标签时, invokeLater 方法更适宜。用户更希望让工作器线程有更快完成工作而不是得到更加精确的进度指示器。
  这两种方法都是在事件分配线程中执行 run 方法。没有新的线程被创建。
原文:https://www.cnblogs.com/zhangmiao14/p/9992471.html