使用wait、notify简单实现并行计算

jdk1.5之后可以使用 Executor、Callable和Future实现多个线程协同工作。

比如有这样的场景:需要从3个数据库中分别查询数据,最后合并结果返回。

如果不用多线程的话,只能先查第1个库,查完放在List中,接着再查第2个库,接着再查第3个库,类似的代码可能是这样的:

List<T> result1 = selectDB1();
List<T> result2 = selectDB2();
List<T> result3 = selectDB3();
// 合并结果返回
result1.addAll(result2);
result1.addAll(result3);


这里selectDB1()、selectDB谐()和selectDB3() 完全可以并行执行,他们之间没有依赖关系,如果我们用3个线程并行地去调用这3个方法,3个方法都有结果返回后再合并,则在多核的环境下应该可以得到更好的查询速度。

而在jdk1.5之前没有 Executor、Callable和Future,那我们如果使用多线程来实现并行计算呢?

下面的代码演示了使用3个线程来并行计算从1累加到300000000L之和。

test3Thread()用3个线程来计算,test1Thread() 只用一个线程来计算,比较下来 test3Thread()比test1Thread()快1倍。

public class TestMoreThread {

	/**
	 * 只用一个线程计算
	 */
	public static void test1Thread(){		
		long result = 0L;
		for(long i=0;i<300000000L;i++){
			result += i;
		}
	}
	
	/**
	 * 使用3个线程计算
	 */
	public static void test3Thread(){
		Object lock = new Object();
		//启动3个线程分成3断同时计算
		Computer c1 = new Computer("T1", lock, 0, 100000000L);
		Computer c2 = new Computer("T2", lock, 100000001L, 200000000L);
		Computer c3 = new Computer("T3", lock, 200000001L, 300000000L);

		new Thread(c1).start();
		new Thread(c2).start();
		new Thread(c3).start();
		// 判断3个线程是否都计算完成
		while (!c1.getStatus() || !c2.getStatus() || !c3.getStatus()) {
			synchronized (lock) {
				try {
					// 在这里释放锁和CUP控制权,当有子线程的状态改变后会唤配它继续执行
					lock.wait();
				} catch (InterruptedException e) {
					e.printStackTrace();
				}
			}			
		}
		// 在这里合并3个线程的计算结果
		System.out.println((c1.getResult()+c2.getResult()+c3.getResult()));
	}
	
	
	public static void main(String[] args) {
		long begin = System.currentTimeMillis();
		test3Thread();
		System.out.println("Take me for "+(System.currentTimeMillis()-begin)+" ms");
	}
}

/**
 * 执行子任务的子线程
 * @author bruce
 *
 */
class Computer implements Runnable {
	private boolean status = false;
	private long result;
	private Object lock;
	private String name;
	private long begin;
	private long end;
	

	public Computer(String name, Object lock, long begin, long end) {
		this.begin = begin;
		this.end = end;
		this.lock = lock;
		this.name = name;
	}

	@Override
	public void run() {
		long sum = 0;
		for (long i = begin; i <= end; ++i) {
			sum += i;
		}
		this.result = sum;
		this.status = true;
		//计算完后唤醒主线程
		synchronized (lock) {
			lock.notify();
		}
		System.out.println(name+":"+sum);
	}
	
	public long getResult(){
		return this.result;
	}
	
	public boolean getStatus(){
		return this.status;
	}
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

wxwyes

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值