一个线程(像主线程)有时候需要开始一个其它线程去执行大量数据的计算、下载文件或执行耗时的活动。在完成其它任务之后,这个线程就会开始工作线程,而这个工作线程已经准备好了去执行工作线程的结果返回和等待工作线程完成和死亡。
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 computation
private static final BigDecimal FOUR = BigDecimal.valueOf(4);
// rounding mode to use during pi computation
private 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);
else
result = 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.1415926535897932384626433832795028841971693993751058209749445923078164062
862089986280348253421170679821480865132823066470938446095505822317253594081
284811174502841027019385211055596446229489549303819644288109756659334461284
756482337867831652712019091456485669234603486104543266482133936072602491412
737245870066063155881748815209209628292540917153643678925903600113305305488
204665213841469519415116094330572703657595919530921861173819326117931051185
4807446237996274956735188575272489122793818301194912983367336244065664308
6021394946395224737190702179860943702770539217176293176752384674818467669
405132000568127
源码下载:git@github.com:owenwilliam/Thread.git