与大家分享一种多线程实现异步消费的方式。基本思路是开启一个主线程,在主线程内定义一个内部线程类,开启多个内部线程类进行消费;代码如下(不懂的话可以直接复制代码跑一下):
1、首先有一个启动主线程方法
import java.util.concurrent.ScheduledThreadPoolExecutor;
import java.util.concurrent.TimeUnit;
public class Start {
public static void main(String[] args) {
ScheduledThreadPoolExecutor poolExecutor = new ScheduledThreadPoolExecutor(1);
String[] redisPrint = new String[10];
for (int i = 0; i < 10; i++) {
redisPrint[i] = "被消费的数据" + i;
}
poolExecutor.schedule(new DoThing(redisPrint), 0, TimeUnit.SECONDS);
}
}
2、然后就是主线程内真正的异步处理方法,看代码
import java.util.Date;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
public class DoThing implements Runnable {
private static ExecutorService executorService = Executors.newFixedThreadPool(3);//控制真正工作线程数
private String[] redisPrint;
public DoThing(String[] redisPrint) {
this.redisPrint = redisPrint;
}
@Override
public void run() {
System.out.println("主线程启动-----" + Thread.currentThread().getId());
while (true) {
try {
if (redisPrint == null) {
System.out.println("没有要处理的数据"+new Date() );
Thread.sleep(3000l); //主线程睡3秒
continue;
}
for (String item : redisPrint) {
executorService.execute(new toDo(item));//子线程是真正工作的线程,比如从redis中消费数据redis.rpop(key)
}
} catch (Exception ex) {
ex.fillInStackTrace();
} finally {
this.redisPrint = null;
}
}
}
class toDo implements Runnable { //子线程
private String print;
public toDo(String print) {
this.print = print;
}
@Override
public void run() {
System.out.println("线程" + Thread.currentThread().getId() + "工作---" + print);
}
}
}