Java 并发编程知识点学习总结 (1)

Java 并发编程知识点学习总结 (1)

最近在清理思路,准备重新的阶段开始,想把自己过去学习的并发知识转入CSDN上来分享,也希望能得到大牛指点,不断更新学习笔记,欢迎直接留言交流,如转发请说明并附上链接,感谢!

开始:
0、线程类的定义方式
new Thread(); + 重写run()
implements Runnable; + 重写run()

1、对一个实现了Runnable接口的类来说,创建Thread对象并不会创建一个新的执行线程; 调用它的run()方法,也不会创建一个新的执行线程。只有调用它的start()方法时,才会创建一个新的执行线程。

2、线程的ID和status是不允许被修改的(getState()),线程类没有提供setId()和setStatus()方法来修改它们。

3、如果一个Thread是以Runnable对象为参数构建的,那么也可以使用Thread类的静态方法currentThread()来访问这个线程对象。

4、interrupt() interrupted() isInterrupted() 的使用
interrupt() 是用于设置线程对象的中断状态,在线程对象因使用sleep() wait()等方法随之抛出InterruptedException后,其中断状态就会被JVM自动清除,说明interrupt()操作只是用于设置线程对象的标志位(中断位)“Just to set the interrupt flag”。
interrupted() 是Thread的静态方法,在返回当前线程的中断状态标志位后,无论我们是否有通过中断异常的抛出,将立即清除这个中断状态标志位,第一次调用会得到true,第二次调用(因为状态已经清除)就是false,看源码便明白:

public void interrupt() {
    if (this != Thread.currentThread())
        checkAccess();

    synchronized (blockerLock) {
        Interruptible b = blocker;
        if (b != null) {
            interrupt0();           // Just to set the interrupt flag
            b.interrupt(this);
            return;
        }
    }
    interrupt0();
}

public static boolean interrupted() {
    return currentThread().isInterrupted(true);
}

public boolean isInterrupted() {
    return isInterrupted(false);
}
// 返回的同时,按入参执行对线程状态位的清除
private native boolean isInterrupted(boolean ClearInterrupted);

isInterrupted() 是作用于调用该方法的线程对象所对应的线程,只是简单的查询中断状态,不会对状态标志位进行修改,留意源码:

return isInterrupted(false); 

通常以interrupted()操作后,配合在执行线程中使用isInterrupted()判断,执行结束线程的逻辑,而不必抛出中断异常再去catch的处理方法。
参考贴:
http://blog.csdn.net/z69183787/article/details/25076033

5、在主线程逻辑中子执行线程调用 interrupt() 方法后,可以在主线程中对执行线程类thread.isInterrupted()方法确认是否中断,也可以在执行线程逻辑中用Thread.interrupted()来操作中断并得到状态,配合调用它的线程中使用throw new InterruptedException()添加需要的执行线程中断后的逻辑。

6、thread中睡眠功能使用sleep(1000),也可用TimeUtil.SECONDS.sleep(1)。

7、join()
join(int milliseconds)
join(int milli, int nonaseconds);
此3种使用的不同是,当一个线程在其逻辑中调用另一个线程的 join() 时,被调用线程执行结束后再会进行它后面的逻辑,而join(int milliseconds)相当于增加了一个复选条件,即当被调用线程执行结束 或者 调用join(int milli)后时钟到达了milli时间长度就继续运行它后续的逻辑。

8、setDaemon()方法只能在 start() 方法被调用前设置,isDaemon()检查是否守护线程。

9、run()方法没有throws语句;
所以不可能向上抛出异常,在一些未能预知异常的场景下,尤其是使用ExecutorService这类线程池控制实现时,上一层的调用方无法对run()的调用进行捕获,对于执行线程对象来说是直接打印堆栈并退出。
为防止线程溢出以及代码的健壮性和日志记录的完整性,应在执行线程的run()中分别结合使用 try{..}catch(){..} 和 setUncaughtExceptionHandler(UncaughtExceptionHandler exceptionHandler)方法来统一封装并初始化线程对象的运行时未知异常记录。
它能检测到这类异常而产生的线程终结,会通知线程池框架创建新的工作线程来替换,线程资源足够也可能不会,意味着控制了产生线程溢出的风险,并确保了ExcecutorService主线程的执行时配合log4j日志记录的完整(log4j的性能是另一个问题);
在ExecutorService使用下,要么在主线程中为每个执行线程设定setDefaultUncaughtExceptionHandler(),要么在执行线程中设定setUncaughtExceptionHandler()。才可能在执行器框架下有效。
另外,对于 ExecutorService 接口的实现,无论是 Executors.newFixedThreadPool()或Executors.newCachedThreadPool(),只有通过execute提交的任务,才能将它抛出的异常交给UncaughtExceptionHandler,而通过submit提交的任务,无论是抛出的未检测异常还是已检查异常,都将被认为是任务返回状态的一部分。如果一个由submit提交的任务由于抛出了异常而结束,那么这个异常将被Future.get封装在ExecutionException中重新抛出。
参考贴:
http://blog.csdn.net/u013256816/article/details/50417822

10、ThreadLocal varlidate = new ThreadLocal(); + 重写initialValue()方法,声明线程局部变量分别为每个线程存储了各自的属性值,并提供于各自使用,如果线程是第一次访问线程局部变量,线程局部变量可能还没有为它存储值,这个时候重写的initialValue()方法就会被调用,并返回当前线程的值;各线程私有变量的线程安全效果。可以remove()来清除局部变量存储值。其实关于ThreadLocal,有蛮多用处单独再写,它是笔者刚开始开发工作时印象较深的线程工具类,也是向以前岗位上大牛前辈的代码中学习体会到的。

11、InheritableThreadLocal varlidate = new InheritableThreadLocal(); + 重写initialValue()方法,声明的线程局部变量类,是继承了ThreadLocal类,但扩展了可以将局部变量的值传给子线程使用,但这是继承不是共用,子线程获取后的值改变不会影响传值线程的局部变量值。可以重写childValue(T t)方法来初始化子线程特定的局部变量。

12、ThreadGroup类表示一组线程,线程组可以包含线程对象,也可以包含其他的线程组对象,它是一个树形结构。通过list()方法打印线程组对象的信息,activeCount()方法获取线程组包含的线程数目,enumerate()方法获取线程组包含的线程列表,interrupt()方法为中断,只对非线程池控制器的使用有效,使用ExecutorService框架无效。
继承ThreadGroup的线程组类,可以通过重写uncaughtException(Thread t, Throwable e)方法来定义非捕获异常处理器。

13、实现ThreadFactory接口的工厂类,可以修改线程类的创建方式,可以为有资源限制的场景下创建对象的数目,如我们可以限制一个线程类型的对象不多于n个。重写newThread(Runnable r)方法,返回对应的线程实例。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值