Java并发2

P662)后台线程(daemon:守护)

所谓后台(daemon)线程,是指在程序运行的时候在后台提供一种通用服务的线程,并且这种线程并不属于程序中不可或缺的部分。因此,当所有的非后台线程结束时,程序也就终止了,同时会杀死进程中的所有后台进程。反过来说,只要有任何非后台线程还在运行,程序就不会终止。

1 Thread daemon = new Thread(new SimpleDaemon());
2 daemon.setDaemon(true);// Must call before start()
3 daemon.start();

 

 必须在线程启动之前调用setDaemon()方法,才能把它设置后台线程。

 

通过编写定制的ThreadFactory可以定制由Executor创建的线程的属性(后台、优先级、名称):

 1  public class DaemonThreadFactory implements ThreadFactory{
 2       @Override
 3       public Thread newThread(Runnable r) {
 4           Thread t = new Thread(r);
 5           t.setDaemon(true);
 6           return t;
 7       }
 8   }
 9   
10  //  ExecutorService exec = Executors.newCacheThreadPool(
11  //      new DaemonThreadFactory());

可以通过调用isDaemon()方法来确定线程是否是一个后台线程。如果是一个后台线程,那么它可以创建的任何线程将被自动设置为后台线程。

 

P669)加入一个线程

一个线程可以在其他线程之上调用join()方法,其效果是等待一段时间直到第二个线程结束才继续执行。如果某个线程在另一个线程t上调用t.join(),此线程将被挂起,直到目标线程t结束才恢复(直到t.isAlive()返回为假)。也可以在调用join()时带上一个超时参数(单位可以是毫秒,或者毫秒和纳秒),这样如果目标线程在这段时间到期时还没结束的话,join()方法总能返回。对join()方法的调用可以被中断,做法是在调用线程上调用interrupt()方法,这时需要用到try-catch子句。

 

当一个线程在该线程上调用interrupt()时,将给该线程设定一个标志,表明该线程已经被中断。然而,异常捕获时将清理这个标志,所以在catch子句中,在异常被捕获的时候这个标志总是为假。除异常外,这个标志还可用于其他情况,比如线程可能会检查其中断状态。

 

P673)捕获异常

由于线程的本质特性,使得你不能捕获从线程中逃逸的异常。Thread.UncaughtExceptionHandler是Java SE5中的新接口,它允许你在每个Thread对象上都附着者一个异常处理器。Thread.UncaughtExceptionHandler.uncaughtException()会在线程因未捕获的异常临近死亡时被调用。为了使用它,我们可以创建一个新类型的ThreadFactory,它将在每个新创建的Thread对象上附着一个Thread.UncaughtExceptionHandle。我们将这个工程传递给Executors创建新的ExecutorService的方法。

 

如果要在代码中处处使用相同的异常处理器,那么更简单的方式是在Thread类中设置一个静态域,并将这个处理器设置为默认的未捕获异常处理器:

1 Thread.setDefaultUncaughtExceptionHandler(
2     new Thread.UncaughtExceptionHandler());

 

这个处理器只有在不存在线程专有的未捕获异常处理器的情况下才会被调用。系统会检查线程专有版本,如果没有发现,则检查线程组是否有其专有的uncaughtException()方法,如果也没有,再调用defaultUncaughtExceptionHandler。

 

P678)使用显式的Lock对象

Lock对象必须被显示的创建、锁定和释放。当你使用Lock对象时,将这里所示的惯用法内部化是很重要的:紧接着的对lock()的调用,你必须放置在finally子句中带有unlock()的 try-catch语句中。注意,return语句必须在try子句中出现,以确保unlock()不会过早发生,从而将数据暴露给了第二个任务。

 

如果在使用synchronize关键字时,某些事物失败了,那么就会抛出一个异常。但是你没有机会做任何清理工作,以维护系统使其处于良好状态。有了显示的Lock对象,你就可以使用finally子句将系统维护在正确的状态了。

 

ReentrantLock下几种lock方法的区别:

 

 

 

 

 

 

 

 

 

 

posted @ 2017-06-27 23:25  TooLateToLearn!  阅读(168)  评论(0编辑  收藏  举报