與大家分享一種多線程實現異步消費的方式。基本思路是開啓一個主線程,在主線程內定義一個內部線程類,開啓多個內部線程類進行消費;代碼如下(不懂的話可以直接複製代碼跑一下):
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);
}
}
}