线程的并发基础部分小结(一)

一、线程的创建Thread和Runnable两者的优劣思考

在JDK中Thread本身实现了Runnable接口,所以使用实现Runnable接口应该是java最提倡的方式,Runnable和Thread分开使用的好处之一就是就java只支持单继承,如果使用了继承Thread就不能继承其他的类了;其二开发人员无需纠结Thread和Runnable之间的同步块和同步方法之间的内部交互,这种分隔使得对操作的本身与其运行的上下文有着独立的控制。其三,同一个Runnabled对象可以用来初始化其他的线程,也可以用于构造一些轻量级的执行框架(Excutors)。

                                                         

                                                                       图1. JDK Thread 继承图

二、interrupt理解

interrupt()方法不会中断或者终止任何线程。interrupt仅仅是设置一个中断标志,当线程处于wait、sleep、join阻塞时,调用interrupt将抛出InterruptedException异常,JVM会自动清除中断标志(改为false)。利用这一特性可以在捕获到InterruptedException异常的时候,将线程的数据共享进行恢复,以安全停止线程。当线程没有进行阻塞时,调用interrupt方法只是将中断标志设置为true,当线程再次被阻塞的时候,抛出InterruptedException,并清除中断标志(设置为false)。interrupt()方法源码如下:

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

     synchronized (blockerLock) { 
               Interruptible b = blocker; 
               if (b != null) { 
                    interrupt0(); // 仅设置一个中断标志 b.interrupt(this); return; 
               } 
     } 
     interrupt0();
}

isInterrupted()方法只是返回当前线程是否被中断,如果中断则返回true,否则返回false。此方法在任何情况下都不会修改线程的中断标志。isInterrupted()方法源码如下:

public boolean isInterrupted() 
{ 
     return isInterrupted(false); 
} 

//参数说明 是否清除中断标志 
private native boolean isInterrupted(boolean ClearInterrupted);

Thread.interrupted()静态方法返回当前线程的中断状态,并清除中断状态。(一个线程的中断状态是不允许被其他线程清除的) interrupted() 方法源码如下:

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

但是如果调用了Thread.interrupted方法且中断标识还没有被重置,或者是线程处于wait,sleep,join过程中,调用isInterrupted方法将会抛出InterruptedException异常

二、join理解

调用t.join()方法将会暂停执行调用线程(可能是主线程,或者其他线程),直到t线程执行完毕,当调用t.isAlive()返回false时,调用t.join()将直接返回(没有任何意义),所以调用一个没有启动的线程的join()方法也没有任何意义。调用带毫秒数的join(long millis)方法,主线程或者其他线程只会等待millis毫秒,然后又能继续向下继续执行。

public final void join() throws InterruptedException 
{
     //当相应调用下面的方法 join(0); 
} 

public final synchronized void join(long millis) throws InterruptedException 
{       long base = System.currentTimeMillis(); 
        long now = 0; 
        if (millis < 0) { throw new IllegalArgumentException("timeout value is negative");} 
        if (millis == 0) { 
            //当参数为0时,将一直等待,直到isAlive返回false 
            while (isAlive()) { wait(0); } 
        } else {
            while (isAlive()) {
                     long delay = millis - now; 
                     if (delay <= 0) { break; } 
                     wait(delay); 
                     now = System.currentTimeMillis() - base; 
            } 
         } 
}

 

参考:http://ifeve.com/java-concurrency-constructs/

           JDK 源码

 

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值