1.2.2合并线程(Joining Threads)

来源:互联网 发布:csmar数据库 编辑:程序博客网 时间:2024/06/08 06:16

 一个线程(像主线程)有时候需要开始一个其它线程去执行大量数据的计算、下载文件或执行耗时的活动。在完成其它任务之后,这个线程就会开始工作线程,而这个工作线程已经准备好了去执行工作线程的结果返回和等待工作线程完成和死亡。

    Thread提供三个join()方法,这个方法允许线程去等待其它线程,谁调用了object join()方法谁就会死亡。

        (1)void join():无限期等待线程死亡。当任务线程的当前线程被打断,将会抛出InterruptedException。如果这个异常抛出,那么打断状态是明确的。

       (2) void join(long millis):等待minllis毫秒线程死亡。通过 0到millis时间等待——这个join()的方法执行join(0).java.lang.IllegaArgumentException的异常,当millis的数字是不合法时。当任务线程的当前线程被打断,将会抛出InterruptedException。如果这个异常抛出,那么打断状态是明确的。

        (3)void join(long millis, intnanos):等待millis毫秒和nanos纳秒直到线程死亡。当millis不合法或nanos不合法,或nanos大于99999,将会抛出IllegalArgumentException. 当任务线程的当前线程被打断,将会抛出InterruptedException。如果这个异常抛出,那么打断状态是明确的。

package com.owen.thread.chapter1;import java.math.BigDecimal;public class ThreadJoin{// constant used in pi computationprivate static final BigDecimal FOUR = BigDecimal.valueOf(4);// rounding mode to use during pi computationprivate static final int roundingMode = BigDecimal.ROUND_HALF_EVEN;private static BigDecimal result;public static void main(String[] args){Runnable r = () ->{result = computePi(50000);};Thread t = new Thread(r);t.start();try{t.join();}catch (InterruptedException ie){// Should never arrive here because interrupt() is never// called.}System.out.println(result);}/* * Compute the value of pi to the specified number of digits after the * decimal point. The value is computed using Machin's formula: *  * pi/4 = 4*arctan(1/5)-arctan(1/239) *  * and a power series expansion of arctan(x) to sufficient precision. */public static BigDecimal computePi(int digits){int scale = digits + 5;BigDecimal arctan1_5 = arctan(5, scale);BigDecimal arctan1_239 = arctan(239, scale);BigDecimal pi = arctan1_5.multiply(FOUR).subtract(arctan1_239).multiply(FOUR);return pi.setScale(digits, BigDecimal.ROUND_HALF_UP);}/* * Compute the value, in radians, of the arctangent of the inverse of the * supplied integer to the specified number of digits after the decimal * point. The value is computed using the power series expansion for the arc * tangent: *  * arctan(x) = x-(x^3)/3+(x^5)/5-(x^7)/7+(x^9)/9 ... */public static BigDecimal arctan(int inverseX, int scale){BigDecimal result, numer, term;BigDecimal invX = BigDecimal.valueOf(inverseX);BigDecimal invX2 = BigDecimal.valueOf(inverseX * inverseX);numer = BigDecimal.ONE.divide(invX, scale, roundingMode);result = numer;int i = 1;do{numer = numer.divide(invX2, scale, roundingMode);int denom = 2 * i + 1;term = numer.divide(BigDecimal.valueOf(denom), scale, roundingMode);if ((i % 2) != 0)result = result.subtract(term);elseresult = result.add(term);i++;} while (term.compareTo(BigDecimal.ZERO) != 0);return result;}}

这个主线程第一次创建一个runnable去计算pi到50000的数据和明确返回java.math.BigDecimal的对象。这个里应用lambda的函数方法。

   这个线程创建一个Thread对象去执行一个runnable和start的工作线程去执行应用。

   这里关键的是,在主线程中请求join()的方法,这个方法在Thread对象中,处于等待状态直到工作线程死亡。当join()方法发生时,主线程就会输出BigDecimal对象的值。

   上面的例子执行结果可能如下(可能读者输出结果不一样,后面章节会对此问题解决):

 3.141592653589793238462643383279502884197169399375105820974944592307816406286208998628034825342117067982148086513282306647093844609550582231725359408128481117450284102701938521105559644622948954930381964428810975665933446128475648233786783165271201909145648566923460348610454326648213393607260249141273724587006606315588174881520920962829254091715364367892590360011330530548820466521384146951941511609433057270365759591953092186117381932611793105118548074462379962749567351885752724891227938183011949129833673362440656643086021394946395224737190702179860943702770539217176293176752384674818467669405132000568127

  源码下载:git@github.com:owenwilliam/Thread.git



原创粉丝点击