10个线程同步处理1000行消息

多线程,并发,是经常遇到的问题,平时解决的方案也想过很多,比如说现在有1000行消息,需要开10个线程同时处理。

 

之前想过两个方案:

 

方案一: 一次开10个线程,每个线程处理一条消息,等10个线程全部处理结束之后,再开启下10个线程,直到全部处理完毕

缺陷:需要等待其他n - 1个线程结束后,才能同时启动下n个线程

 

方案二: 将1000行消息分割为10份,每100行用一个线程处理。

优点:无等待

缺陷: 分割不均,无法充分利用所有的线程

 

现在想想,上面两个缺点挺多,就又想了两种方案:

 

方案三:使用ConcurrentLinkedQueue<Task>存储所有的Task,然后同时开启n个线程读取Queue.

优点:充分利用所有线程,无等待

缺点:需要将所有的task转移到Queue中,消耗一倍内存

 

方案四:使用java.util.concurrent包,固定数量线程池。

优点:完美解决

缺点:当单个task执行时间很短的时候,线程池中的线程并不会被全部使用,这样很多task就会block在一个线程中,降低执行速率

 

下面贴出每个方案的代码实现,备忘吧,如果有更好的想法,或者更简单的方式,再继续补充~

 

 

public class Task {

	private int id;
	
	public Task(int id) {
		this.id = id;
	}
	
	public void start() {
		System.out.println(Thread.currentThread().getName() + ": start to handle task " + id);

		try {
			Thread.sleep(5000);
		} catch (InterruptedException e) {
			e.printStackTrace();
		}
	}
	
}

 

 

 

import java.util.LinkedList;
import java.util.List;

public class TaskProducer {

	public static List<Task> produce(int count) {
		List<Task> tasks = new LinkedList<Task>();
		
		for(int i = 0; i < count; i ++) {
			tasks.add(new Task(i + 1));
		}
		
		return tasks;
	}
	
}

 

 

 

import java.util.LinkedList;
import java.util.List;

/**
 * 策略1: 每次开启n个线程,等待n个线程全部结束之后,再开启下n个线程,每个线程处理一个task.
 * 缺陷:需要等待其他n - 1个线程结束后,才能同时启动下n个线程
 */
public class Strategy1 {

	public static void main(String[] args) {
		List<Task> tasks = TaskProducer.produce(1000);
		handleTasks(tasks, 10);
		System.out.println("All finished");
	}
	
	public static void handleTasks(List<Task> tasks, int threadCount) {
		int taskCount = tasks.size();
		
		List<Thread> threadHolder = new LinkedList<Thread>();
		for(int i = 0; i < taskCount; i += threadCount) {
			for(int j = 0; j < threadCount && (i + j) < taskCount; j ++) {
				Thread thread = new Thread(new TaskHandler(tasks.get(i + j)));
				threadHolder.add(thread);
				thread.start();
			}
			
			waitToFinish(threadHolder);
			threadHolder.clear();
		}
	}
	
	public static void waitToFinish(List<Thread> threadHolder) {
		while(true) {
			boolean allFinished = true;
			for(Thread thread : threadHolder) {
				allFinished = allFinished && !thread.isAlive();
			}
			
			if(allFinished) {
				break;
			}
		}
	}
	
	public static class TaskHandler implements Runnable {
		private Task task;
		
		public TaskHandler(Task task) {
			this.task = task;
		}

		@Override
		public void run() {
			task.start();
		}
	}
	
}

 

 

 

import java.math.BigDecimal;
import java.math.RoundingMode;
import java.util.ArrayList;
import java.util.LinkedList;
import java.util.List;

/**
 * 策略2: 将所有的task分割成n个子task列表,然后开启n个线程,每个线程处理一个子列表
 * 优点:无等待
 * 缺陷: 分割不均,无法充分利用所有的线程
 */
public class Strategy2 {

	public static void main(String[] args) {
		List<Task> tasks = TaskProducer.produce(1000);
		handleTasks(tasks, 10);
		System.out.println("All finished");
	}

	public static void handleTasks(List<Task> tasks, int threadCount) {
		List<List<Task>> splitTasks = splitTasksToNThreads(tasks, threadCount);

		List<Thread> threadHolder = new LinkedList<Thread>();
		for (List<Task> segment : splitTasks) {
			Thread thread = new Thread(new TaskHandler(segment));
			threadHolder.add(thread);
			thread.start();
		}
		
		waitToFinish(threadHolder);
	}
	
	public static void waitToFinish(List<Thread> threadHolder) {
		while(true) {
			boolean allFinished = true;
			for(Thread thread : threadHolder) {
				allFinished = allFinished && !thread.isAlive();
			}
			
			if(allFinished) {
				break;
			}
		}
	}
	
	public static List<List<Task>> splitTasksToNThreads(List<Task> tasks, int threadCount) {
		List<List<Task>> splitTasks = new ArrayList<List<Task>>(threadCount);

		int taskCount = tasks.size();
		int taskPerThread = new BigDecimal(taskCount).divide(new BigDecimal(threadCount), RoundingMode.CEILING).intValue();

		for (int i = 0; i < taskCount; i += taskPerThread) {
			List<Task> segment = new LinkedList<Task>();
			for (int j = 0; j < taskPerThread && (i + j) < taskCount; j++) {
				segment.add(tasks.get(i + j));
			}

			splitTasks.add(segment);
		}

		tasks.clear();
		
		return splitTasks;
	}
	
	public static class TaskHandler implements Runnable {
		private List<Task> tasks;

		public TaskHandler(List<Task> tasks) {
			this.tasks = tasks;
		}
		
		@Override
		public void run() {
			for (Task task : tasks) {
				task.start();
			}
		}
	}

}

 

 

 

import java.util.LinkedList;
import java.util.List;
import java.util.Queue;
import java.util.concurrent.ConcurrentLinkedQueue;

/**
 * 策略3: 使用ConcurrentLinkedQueue<Task>存储所有的Task,然后同时开启n个线程读取Queue.
 * 优点:充分利用所有线程,无等待
 * 缺点:需要将所有的task转移到Queue中,消耗一倍内存
 */
public class Strategy3 {

	public static void main(String[] args) {
		List<Task> tasks = TaskProducer.produce(1000);
		handleTasks(tasks, 10);
		System.out.println("All finished");
	}
	
	public static void handleTasks(List<Task> tasks, int threadCount) {
		Queue<Task> taskQueue = new ConcurrentLinkedQueue<Task>();
		taskQueue.addAll(tasks);
		
		List<Thread> threadHolder = new LinkedList<Thread>();
		for(int i = 0; i < threadCount; i ++) {
			Thread thread = new Thread(new TaskHandler(taskQueue));
			threadHolder.add(thread);
			thread.start();
		}
		
		waitToFinish(threadHolder);
	}
	
	public static void waitToFinish(List<Thread> threadHolder) {
		while(true) {
			boolean allFinished = true;
			for(Thread thread : threadHolder) {
				allFinished = allFinished && !thread.isAlive();
			}
			
			if(allFinished) {
				break;
			}
		}
	}
	
	public static class TaskHandler implements Runnable {
		
		private final Queue<Task> tasks;
		
		public TaskHandler(Queue<Task> tasks) {
			this.tasks = tasks;
		}
		
		public void run() {
			while(!tasks.isEmpty()) {
				Task task = tasks.poll();
				if(task != null) {
					task.start();
				}
			}
		}
		
	}
	
}

 

 

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

/**
 * 策略4: 使用java.util.concurrent包,线程池。
 * 优点:完美解决。
 */
public class Strategy4 {

	public static void main(String[] args) {
		List<Task> tasks = TaskProducer.produce(1000);
		handleTasks(tasks, 10);
		System.out.println("All finished");
	}
	
	public static void handleTasks(List<Task> tasks, int threadCount) {
		try {
			ExecutorService executor = Executors.newFixedThreadPool(threadCount);
			
			for(Task task : tasks) {
				executor.submit(new TaskHandler(task));
			}
			
			executor.shutdown();
			executor.awaitTermination(60, TimeUnit.SECONDS);
		} catch (Exception e) {
			e.printStackTrace();
		}
	}
	
	public static class TaskHandler implements Runnable {

		private Task task;
		
		public TaskHandler(Task task) {
			this.task = task;
		}
		
		public void run() {
			task.start();
		}
		
	}
	
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值