java控制线程(一)
2019-01-10 本文已影响0人
RoundYuan
java控制线程(一)
控制线程-join方法
java的线程支持提供了一些便捷的工具方法:
join线程:Thread提供了让一个线程等待另一个线程完成的方法-join()方法。
当某个程序执行流中调用其他线程的join()方法时,调用线程将被阻塞,直到被join()方法加入的join线程执行完
为止。
join()方法通常由使用线程的程序调用,以将大问题划分成许多小文题,每个小问题分配一个线程。当所有的小问题
都得到处理后,再调用主线程来进一步操作。
示例代码:
public class JoinThread extends Thread {
//提供一个有参数的构造器,用于设置该线程的名字
public JoinThread(String name)
{
super(name);
}
//重写run()方法,定义线程执行体
@Override
public void run() {
for (int i=0;i<100;i++)
{
System.out.println(getName()+" "+i);
}
}
public static void main(String[] args) throws InterruptedException {
//启动子线程
new JoinThread("新线程").start();
for (int i=0;i<100;i++)
{
if (i==20)
{
JoinThread jt=new JoinThread("被join的线程");
jt.start();
//main线程调用了jt线程的join方法,main方法
//必须等jt执行结束才会向下执行
jt.join();
}
System.out.println(Thread.currentThread().getName()+"---"+i);
}
}
}
上面程序中一共有三个线程,主方法开始时就启动了名为“新线程”的子线程,该子线程将会和main线程并发执行。
当主线程的循环变量i等于20时,启动了名为“被join的线程”的线程,该线程不会和main线程并发执行,main线程必须
等该线程执行结束后才可以向下执行。在名为"被Join的线程"的线程执行时,实际上只有2个子线程并发执行
而主线程处于等待状态。结果如下
主线程执行到i==20时启动,并join了名为“被join的线程”的线程,所以主线程将一直处于阻塞状态,直到名为
“被join的线程”的线程执行完成。
join()方法有如下3种重载方式。
1、join():等待被join的线程执行完成。
如上
2、join(long millis) :等待被join的线程的时间最长为millis毫秒。如果在millis毫秒内被join的线程还没有执行
结束,则不再等待。
将上面的代码做如下修改
if (i==20)
{
JoinThread jt=new JoinThread("被join的线程");
jt.start();
//main线程调用了jt线程的join方法,main方法
//必须等jt执行结束才会向下执行
jt.join(9);
}
结果如下:
JoinThread运行结果2.png3、join(long millis,int nanos):
等待被join的线程的时间最长为mills毫秒加nanos毫微秒。
!第三个很少用,单位太小软件和硬件都无法精确。
java中的源代码如下
源代码:
public final void join() throws InterruptedException {
join(0);
}
public final synchronized void join(long millis, int nanos)
throws InterruptedException {
if (millis < 0) {
throw new IllegalArgumentException("timeout value is negative");
}
if (nanos < 0 || nanos > 999999) {
throw new IllegalArgumentException(
"nanosecond timeout value out of range");
}
if (nanos >= 500000 || (nanos != 0 && millis == 0)) {
millis++;
}
join(millis);
}
最后实现核心都是下面这个:
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;
}
}
}