如果是单线程处理一批事情,例如,有16个日志需要处理,各个日志之间是独立的,假设处理每个的时间是1秒, 一共需要处理16秒才能处理完。
现在使用多线程来加速处理时间,思路:
创建4个线程,每个线程从一个任务列表中获取一个任务,进行处理,处理完后,再获取一个,直到任务被处理完。
因为每个任务(处理日志)是独立的,因此,每个线程就是独占该任务资源,因此处理任务时并不需要加锁,需要加锁的是任务列表,多个线程竞争的是任务列表。
这里我们使用BlockingQueue阻塞队列。
当队列为空时,如果要取元素就进入等待状态,当队列已满是,如果继续添加则进入等待状态。非常适合生产消费者模型。
public class Log {
private String content; //日志的内容
public Log(String content) {
this.content = content;
}
void parseLog() {
try {
Thread.sleep(1000);
System.out.println("打印日志"+content);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
public class ThreadA extends Thread{
private BlockingQueue<Log> logs;
public ThreadA(BlockingQueue<Log> logs) {
this.logs = logs;
}
public void run() {
while(true) {
try {
logs.take().parseLog(); //如果队列为空,就等待
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
public static void main(String[] args) {
final BlockingQueue<Log> logs = new ArrayBlockingQueue<Log>(16);
for(int i=0;i<16;i++) {
logs.add(new Log("日志 "+i)); //想队列中添加要处理的log对象
}
ThreadA[] threads = new ThreadA[4];
for(int i=0;i<4;i++) {
threads[i] = new ThreadA(logs); //所有线程竞争同一个队列
}
for(int i=0;i<4;i++) {
threads[i].start();
}
}
运行结果:
打印日志 0
打印日志 3
打印日志 2
打印日志 1
打印日志 4
打印日志 7
打印日志 6
打印日志 5
打印日志 8
打印日志 9
打印日志 11
打印日志 10
打印日志 12
打印日志 15
打印日志 14
打印日志 13
如果使用Vector也是可以的,Vector是线程安全的