设为首页 加入收藏

TOP

Java主线程等待子线程、线程池 (三)
2014-11-24 10:24:25 】 浏览:10861
Tags:Java 线程 等待
s Main
{
public static void main(String[] args)
{
long start = System.currentTimeMillis();

// 创建一个初始值为5的倒数计数器
CountDownLatch countDownLatch = new CountDownLatch(5);
for(int i = 0; i < 5; i++)
{
Thread thread = new TestThread(countDownLatch);
thread.start();
}

try
{
// 阻塞当前线程,直到倒数计数器倒数到0
countDownLatch.await();
}
catch (InterruptedException e)
{
e.printStackTrace();
}

long end = System.currentTimeMillis();
System.out.println("子线程执行时长:" + (end - start));
}
}

public class Main
{
public static void main(String[] args)
{
long start = System.currentTimeMillis();

// 创建一个初始值为5的倒数计数器
CountDownLatch countDownLatch = new CountDownLatch(5);
for(int i = 0; i < 5; i++)
{
Thread thread = new TestThread(countDownLatch);
thread.start();
}

try
{
// 阻塞当前线程,直到倒数计数器倒数到0
countDownLatch.await();
}
catch (InterruptedException e)
{
e.printStackTrace();
}

long end = System.currentTimeMillis();
System.out.println("子线程执行时长:" + (end - start));
}
}


执行结果:

Thread-0子线程开始

Thread-2子线程开始

Thread-1子线程开始

Thread-3子线程开始

Thread-4子线程开始

Thread-2子线程结束

Thread-4子线程结束

Thread-1子线程结束

Thread-0子线程结束

Thread-3子线程结束

子线程执行时长:5000

注意:如果子线程中会有异常,那么countDownLatch.await()应该写在finally里面,这样才能保证异常后也能对计数器减1,不会让主线程永远等待。

另外,await()方法还有一个实用的重载方法:public booleanawait(long timeout, TimeUnit unit),设置超时时间。

例如上面的代码,想要设置超时时间10秒,到了10秒无论是否倒数完成到0,都会不再阻塞主线程。返回值是boolean类型,如果是超时返回false,如果计数到达0没有超时返回true。

[java] // 设置超时时间为10秒
boolean timeoutFlag = countDownLatch.await(10,TimeUnit.SECONDS);
if(timeoutFlag)
{
System.out.println("所有子线程执行完成");
}
else
{
System.out.println("超时");
}

// 设置超时时间为10秒
boolean timeoutFlag = countDownLatch.await(10,TimeUnit.SECONDS);
if(timeoutFlag)
{
System.out.println("所有子线程执行完成");
}
else
{
System.out.println("超时");
}


4、主线程等待线程池

Java线程池java.util.concurrent.ExecutorService是很好用的多线程管理方式。ExecutorService的一个方法boolean awaitTermination(long timeout, TimeUnit unit),即阻塞主线程,等待线程池的所有线程执行完成,用法和上面所说的CountDownLatch的public boolean await(long timeout,TimeUnit unit)类似,参数设置一个超时时间,返回值是boolean类型,如果超时返回false,如果线程池中的线程全部执行完成,返回true。

由于ExecutorService没有类似CountDownLatch的无参数的await()方法,只能通过awaitTermination来实现主线程等待线程池。

[java] public class Main
{
public static void main(String[] args)
{
long start = System.currentTimeMillis();

// 创建一个同时允许两个线程并发执行的线程池
ExecutorService executor = Executors.newFixedThreadPool(2);
for(int i = 0; i < 5; i++)
{
Thread thread = new TestThread();
executor.execute(thread);
}
executor.shutdown();

try
{
// awaitTermination返回false即超时会继续循环,返回true即线程池中的线程执行完成主线程跳出循环往下执行,每隔10秒循环一次
while (!executor.awaitTermination(10, TimeUnit.SECONDS));
}
catch (InterruptedException e)
{
e.printStackTrace();
}

long end = System.currentTimeMillis();
System.out.println("子线程执行时长:" + (end - start));
}
}

public class Main
{
public static void main(String[] args)
{
lon

首页 上一页 1 2 3 4 下一页 尾页 3/4/4
】【打印繁体】【投稿】【收藏】 【推荐】【举报】【评论】 【关闭】 【返回顶部
上一篇eclipse/myeclipse使用技巧 下一篇Java建议:推荐使用String直接量..

最新文章

热门文章

Hot 文章

Python

C 语言

C++基础

大数据基础

linux编程基础

C/C++面试题目