多线程countDownLatch方法介绍

CountDownLatch介绍

CountDownLatch是一个同步辅助类,在完成一组正在其他线程中执行的操作之前,它允许一个或多个线程一直等待。在一些应用场合中,需要等待某个条件达到要求后才能做后面的事情;同时当线程都完成后也会触发事件,以便进行后面的操作。 这个时候就可以使用CountDownLatch。

本文主要介绍CountDownLatch的一个具体使用——字符串敏感字过滤。字符串敏感字过滤是一个常用的功能点,这里使用的敏感字过滤方法主要参考 敏感词过滤算法实现这边博客。而使用CountDownLatch的主要目的是为了提高敏感字过滤的效率。

//将字符串按照每1024个字符一组进行截取
private static final int PRE_LENGTH = 1024;

public String filter(String textStr) {
		int length = textStr.length();
		int latchCount = length / PRE_LENGTH + 1;
		String[] temp = new String[latchCount];
		Worker[] workerGroup = new Worker[latchCount];
		for (int i = 0; i < latchCount; i++) {
			if (i + 1 == latchCount) {
				// 最后一次
				temp[i] = textStr.substring(i * PRE_LENGTH);
			} else {
				temp[i] = textStr.substring(i * PRE_LENGTH, (i + 1) * PRE_LENGTH);
			}
		}
		StringBuilder builder = new StringBuilder(length);
		CountDownLatch latch = new CountDownLatch(latchCount);
		for (int i = 0; i < latchCount; i++) {
			workerGroup[i] = new Worker(temp[i], sw, latch);
			workerGroup[i].start();
		}
		try {
			latch.await();
			for (Worker tempWorker : workerGroup) {
				builder.append(tempWorker.textStr);
			}
		} catch (InterruptedException e) {
			e.printStackTrace();
		}

		return builder.toString();

	}




static class Worker extends Thread {
		String textStr;
		String replaceStr;
		KWSeeker kwseeker;
		CountDownLatch latch;

		public Worker(String textStr, KWSeeker kwseeker, CountDownLatch latch) {
			this.textStr = textStr;
			this.kwseeker = kwseeker;
			this.latch = latch;
		}

		public void run() {
			try {
				textStr = doWork();
			} catch (Exception e) {
				e.printStackTrace();
			} finally {
				latch.countDown();
			}
		}

		private String doWork() {
			String str = kwseeker.replace(textStr, fragment);
			return str;
		}
	}



我们可以看到:
1、CountDownLatch初始化的count为字符串按照每1024个字节截取的数组数量 latchCount
2、创建 latchCount 个线程,并执行
3、只有当所有线程执行完成,并调用 latch.countDown()后 latch.await()会被唤起,继续执行后续的代码。

测试代码
protected List<Keyword> init() {
		List<Keyword> words = new ArrayList<>();
		try {
			for (String line : TextLineIO
					.lineSeq("D:\\keyword.txt")) {
				words.add(new Keyword(line));
			}
		} catch (Throwable e) {
			e.printStackTrace();
		}
		return words;
	}


public static void main(String[] args) throws IOException {
		Testkeyword t = new Testkeyword();
		t.init();
		String path="D:\\word.txt";
		BufferedReader reader = new BufferedReader(new InputStreamReader(new FileInputStream(path)));
		StringBuffer buffer = new StringBuffer();
		String line = " ";
		while ((line = reader.readLine()) != null){
		buffer.append(line);
		}
		String textStr=buffer.toString();
		System.out.println("过滤字符串长度:"+textStr.length());
		long begin=System.currentTimeMillis();
		t.filter(textStr);
		System.out.println("消耗时间:"+(System.currentTimeMillis()-begin)+"ms");
	}




测试结果:
--------未使用多线程-----------
过滤字符串长度:31878
消耗时间:215ms

-------使用多线程--------------
过滤字符串长度:31878
消耗时间:47ms

猜你喜欢

转载自cpjsjxy.iteye.com/blog/2272451
今日推荐