Java并发--线程计数器

Java中经常存在以下的需求,启动多个相同或者不同的线程,主线程需要等待所有的线程执行完才继续往下执行

要实现上面的需求,基本的思路: 创建一个计数器, 来记录线程的执行

有两种实现方法

方法1:

使用锁和计数器:需要有一个对象锁,作用一:保证这个计数器的线程安全,作用二:阻塞主线程,等待所有线程执行完再来唤醒主线程继续执行

方法2:

使用Java线程包中的CountDownLatch:不需要加锁, 不需要wait notify这么复杂

方法1:

package com.yaya.thread.threadCount.count;

import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

public class TestCount {

	int count = 0;

	int total = 0;

	Object object = new Object();

	void testCount() {
		total = 10;
		ExecutorService pool = Executors.newFixedThreadPool(5);
		for (int i = 0; i < 10; i++) {
			final int j = i;
			Runnable runnable = new Runnable() {

				@Override
				public void run() {
					// TODO Auto-generated method stub
					try {
						System.out.println("runnalbe:" + j);
						Thread.sleep(2000);
					} catch (InterruptedException e) {
						// TODO Auto-generated catch block
						e.printStackTrace();
					} finally {
						synchronized (object) {
							count++;
							if (count == total) {
								object.notify();
							}
						}
					}

				}

			};
			pool.execute(runnable);

		}
		synchronized (object) {
			if (count != total) {
				try {
					object.wait();
				} catch (InterruptedException e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				}
			}
		}
		System.out.println("end");
		pool.shutdown();
	}

	public static void main(String[] args) {
		TestCount testCount = new TestCount();
		testCount.testCount();
	}

}

方法2: CountDownLatch

package com.yaya.thread.threadCount.countDownLatch;

import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.Callable;
import java.util.concurrent.CountDownLatch;

import com.yaya.thread.future.ThreadPoolUtil;

public class TestCountDownLatch {

	static CountDownLatch count = null;
	
	public void testRunnalbe(){
		List<String> list = new ArrayList<String>();
		for (int i = 1; i <= 10; i++) {
			list.add("list" + i);
		}
		count = new CountDownLatch(list.size());

		List<Runnable> runnables = new ArrayList<Runnable>();

		for (int i = 0; i < list.size(); i++) {
			final String listName = list.get(i);
			Runnable runnable = new TestRunnable1(listName, count);
			runnables.add(runnable);
		}

		try {
			ThreadPoolUtil.exeRunnableList(runnables);

		} catch (Exception e) {
			System.err.println(e.getMessage());
		}
		try {
			count.await();
			System.out.println("end");
			ThreadPoolUtil.shutDown(true);
		} catch (InterruptedException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}

	}
	
	
	public void testDifferentRunnalbes(){
		List<String> list = new ArrayList<String>();
		for (int i = 1; i <= 10; i++) {
			list.add("list" + i);
		}
		count = new CountDownLatch(list.size()*2);

		List<Runnable> runnables = new ArrayList<Runnable>();

		for (int i = 0; i < list.size(); i++) {
			final String listName = list.get(i);
			Runnable runnable = new TestRunnable1(listName, count);
			runnables.add(runnable);
		}
		
		for (int i = 0; i < list.size(); i++) {
			final String listName = list.get(i);
			Runnable runnable = new TestRunnable2(listName, count);
			runnables.add(runnable);
		}

		try {
			ThreadPoolUtil.exeRunnableList(runnables);

		} catch (Exception e) {
			System.err.println(e.getMessage());
		}
		try {
			count.await();
			System.out.println("end");
			ThreadPoolUtil.shutDown(true);
		} catch (InterruptedException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}

	}

	public static void main(String[] args) {
		TestCountDownLatch  testCountDownLatch  = new TestCountDownLatch();
		testCountDownLatch.testDifferentRunnalbes();
	}

}
package com.yaya.thread.threadCount.countDownLatch;

import java.util.concurrent.CountDownLatch;

public class TestRunnable2 implements Runnable {

	String appid;

	CountDownLatch count;

	public TestRunnable2(String appid, CountDownLatch count) {
		super();
		this.appid = appid;
		this.count = count;
	}

	@Override
	public void run() {
		System.out.println("task" + this.appid + "开始");
		try {
			Thread.sleep(3000);
		} catch (InterruptedException e) {
			e.printStackTrace();
		}
		System.out.println("task" + this.appid + "睡了3s");
		count.countDown();

	}

}

package com.yaya.thread.future;

import java.util.List;
import java.util.concurrent.Callable;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.Future;
import java.util.concurrent.LinkedBlockingQueue;
import java.util.concurrent.ThreadFactory;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.TimeoutException;
import java.util.concurrent.atomic.AtomicInteger;

public class ThreadPoolUtil {

	// 线程池
	private static ThreadPoolExecutor threadPool;

	// 线程池核心线程数
	private static final int CORE_POOL_SIZE = 5;

	// 线程池最大线程数
	private static final int MAX_POOL_SIZE = 10;

	// 额外线程空状态生存时间
	private static final int KEEP_ALIVE_TIME = 10000;

	private static final int CANCEL_TASK_TIME = 20;

	private ThreadPoolUtil() {

	}

	static {
		threadPool = new ThreadPoolExecutor(CORE_POOL_SIZE, MAX_POOL_SIZE, KEEP_ALIVE_TIME, TimeUnit.SECONDS,
				new LinkedBlockingQueue<>(30), new ThreadFactory() {
					private final AtomicInteger integer = new AtomicInteger();

					@Override
					public Thread newThread(Runnable r) {
						return new Thread(r, "mock thread:" + integer.getAndIncrement());
					}
				});
	}

	/**
	 * 从线程池中抽取线程,执行指定的Runnable对象
	 * 
	 * @param runnable
	 */
	public static void execute(Runnable runnable) {
		threadPool.execute(runnable);
	}

	/**
	 * 批量执行 Runnable任务
	 * 
	 * @param runnableList
	 */
	public static void exeRunnableList(List<Runnable> runnableList) {
		for (Runnable runnable : runnableList) {
			threadPool.execute(runnable);
		}
	}

	/**
	 * 从线程池中抽取线程,执行指定的Callable对象
	 * 
	 * @param callable
	 * @return 返回执行完毕后的预期结果
	 */
	public static Future exeCallable(Callable<String> callable) {
		return threadPool.submit(callable);
	}

	/**
	 * 批量执行 Callable任务
	 * 
	 * @param callableList
	 *            callable的实例列表
	 * @return 返回指定的预期执行结果
	 */
	public static List<Future<String>> exeCallableList(List<Callable<String>> callableList) {
		List<Future<String>> futures = null;
		try {
			for (Callable<String> task : callableList) {
				threadPool.submit(task);
			}
			futures = threadPool.invokeAll(callableList);
		} catch (InterruptedException e) {
			e.printStackTrace();
		}
		return futures;
	}

	/**
	 * 批量执行 Callable任务, 但不等待执行完
	 * 
	 * @param callableList
	 *            callable的实例列表
	 * @return 返回指定的预期执行结果
	 */
	public static void exeCallableListNoReturn(List<Callable<String>> callableList) {
		for (Callable<String> task : callableList) {
			threadPool.submit(task);
		}

	}

	/**
	 * 中断任务的执行
	 * 
	 * @param isForceClose
	 *            true:强制中断 false:等待任务执行完毕后,关闭线程池
	 */
	public static void shutDown(boolean isForceClose) {
		if (isForceClose) {
			threadPool.shutdownNow();
		} else {
			threadPool.shutdown();
		}
	}

	/**
	 * 若超出CANCEL_TASK_TIME的时间,没有得到执行结果,则尝试中断线程
	 * 
	 * @param future
	 * @return 中断成功,则返回true 否则返回false
	 */
	public static boolean attemptCancelTask(Future future) {
		boolean cancel = false;
		try {
			future.get(CANCEL_TASK_TIME, TimeUnit.MINUTES);
			cancel = true;
		} catch (InterruptedException e) {
			e.printStackTrace();
		} catch (ExecutionException e) {
			e.printStackTrace();
		} catch (TimeoutException e) {
			cancel = future.cancel(true);
			e.printStackTrace();
		}
		return cancel;
	}

}


  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值