当前位置:天才代写 > tutorial > JAVA 教程 > 深入浅出Java多线程(1)-要领join

深入浅出Java多线程(1)-要领join

2017-11-10 08:00 星期五 所属: JAVA 教程 浏览:661

副标题#e#

对付Java开拓人员,多线程应该是必需纯熟应用的常识点,出格是开拓基于 Java语言的产物。本文将深入浅出的表述Java多线程的常识点,在后续的系列里 将偏重于Java5由Doug Lea传授提供的Concurrent并行包的设计思想以及详细实 现与应用。

如何才气深入浅出呢,我的领略是带着问题,而不是平常的看。所以该系列 根基以办理问题为主,虽然我也很是但愿读者可以或许提出更好的办理问题的方案以 及提出更多的问题。由于程度有限,假如有什么错误之处,请各人提出,配合讨 论,总之,我但愿通过该系列我们可以或许深入领略Java多线程来办理我们实际开拓 的问题。

作为开拓人员,我想没有须要接头多线程的基本常识,好比什么是线程?如何建设等 ,这些常识点是可以通过书本和Google得到的。本系列主要是如何理 深入解多线程来辅佐我们平时的开拓,好比线程池如何实现?如何应用锁等。  

(1)要领Join是干啥用的? 简朴答复,同步,如何同步? 怎么实现的? 下面将逐个答复。

自从打仗Java多线程,一直对Join领略不了。JDK是这样说的:

join
   public final void join(long millis)throws InterruptedException
   Waits at most millis milliseconds for this thread to die. A timeout of 0 means to wait forever.

各人能领略吗? 字面意思是期待一段时间直到这个线程灭亡,我的疑问是那 个线程,是它自己的线程照旧挪用它的线程的,上代码:

package concurrentstudy;
/**
*
* @author vma
*/
public class JoinTest {
   public static void main(String[] args) {
     Thread t = new Thread(new RunnableImpl());
     t.start();
     try {
       t.join(1000);
       System.out.println("joinFinish");
     } catch (InterruptedException e) {
       // TODO Auto-generated catch block
       e.printStackTrace();
     }
   }
}
class RunnableImpl implements Runnable {
   @Override
   public void run() {
     try {
       System.out.println("Begin sleep");
       Thread.sleep(1000);
      System.out.println("End sleep");
     } catch (InterruptedException e) {
       e.printStackTrace();
     }
   }
}

功效是:

Begin sleep
End sleep
joinFinish


#p#副标题#e#

大白了吧,当main线程挪用t.join时,main线程期待t线程,期待时间是1000 ,假如t线程Sleep 2000呢

public void run() {
     try {
       System.out.println("Begin sleep");
       // Thread.sleep(1000);
       Thread.sleep(2000);
      System.out.println("End sleep");
     } catch (InterruptedException e) {
       e.printStackTrace();
     }
   }

功效是:

Begin sleep

joinFinish

End sleep

也就是说main线程只等1000毫秒,不管T什么时候竣事,假如是t.join()呢, 看代码:

public final void join() throws InterruptedException {
   join(0);
   }

就是说假如是t.join() = t.join(0) 0 JDK这样说的 A timeout of 0 means to wait forever 字面意思是永远期待,是这样吗?

其实是比及t竣事后。

这个是怎么实现的吗? 看JDK代码:

/**
   * Waits at most <code>millis</code> milliseconds for this thread to
   * die. A timeout of <code>0</code> means to wait forever.
   *
   * @param   millis  the time to wait in milliseconds.
   * @exception InterruptedException if any thread has interrupted
   *       the current thread. The <i>interrupted status</i> of the
   *       current thread is cleared when this exception is thrown.
   */
   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) {
     while (isAlive()) {
     wait(0);
     }
   } else {
     while (isAlive()) {
     long delay = millis - now;
     if (delay <= 0) {
       break;
     }
     wait(delay);
     now = System.currentTimeMillis() - base;
     }
   }
   }

#p#副标题#e#

#p#分页标题#e#

其实Join要领实现是通过wait(小提示:Object 提供的要领)。 当main线 程挪用t.join时候,main线程会得到线程工具t的锁(wait 意味着拿到该工具的 锁),挪用该工具的wait(期待时间),直到该工具叫醒main线程,好比退出后。

这就意味着main 线程挪用t.join时,必需可以或许拿到线程t工具的锁,假如拿 不到它是无法wait的,刚开的例子t.join(1000)不是说明白main线程期待1秒, 假如在它期待之前,其他线程获取了t工具的锁,它期待时间可不就是1毫秒了。 上代码先容:

/*
* To change this template, choose Tools | Templates
* and open the template in the editor.
*/
package concurrentstudy;
/**
*
* @author vma
*/
public class JoinTest {
   public static void main(String[] args) {
     Thread t = new Thread(new RunnableImpl());
    new ThreadTest(t).start();
     t.start();
     try {
       t.join();
       System.out.println("joinFinish");
     } catch (InterruptedException e) {
       // TODO Auto-generated catch block
       e.printStackTrace();
     }
   }
}
class ThreadTest extends Thread {
   Thread thread;
   public ThreadTest(Thread thread) {
     this.thread = thread;
   }
   @Override
   public void run() {
     holdThreadLock();
   }
   public void holdThreadLock() {
     synchronized (thread) {
       System.out.println("getObjectLock");
       try {
         Thread.sleep(9000);
       } catch (InterruptedException ex) {
       ex.printStackTrace();
       }
       System.out.println("ReleaseObjectLock");
     }
   }
}
class RunnableImpl implements Runnable {
   @Override
   public void run() {
     try {
       System.out.println("Begin sleep");
       Thread.sleep(2000);
      System.out.println("End sleep");
     } catch (InterruptedException e) {
       e.printStackTrace();
     }
   }
}

在main要领中 通过new ThreadTest(t).start();实例化ThreadTest 线程对 象, 它在holdThreadLock()要领中,通过 synchronized (thread),获取线程 工具t的锁,并Sleep(9000)后释放,这就意味着,纵然

main要领t.join(1000),期待一秒钟,它必需期待ThreadTest 线程释放t锁后 才气进入wait要领中,它实际期待时间是9000+1000 MS

运行功效是:

getObjectLock
Begin sleep
End sleep
ReleaseObjectLock
joinFinish

小结:

本节主要深入浅出join及JDK中的实现。

 

    关键字:

天才代写-代写联系方式