0
這是Java 7 Concurrency Cookbook的練習。目標是讓多個生產者將事件寫入共享隊列,並且清理任務(守護進程線程)將從隊列中刪除超過5秒的事件。(查找代碼如下) 如果我嘗試爲此編寫測試或在main()程序,它只在隊列中插入3個項目並退出。 我的問題:如果WriterTask中存在for循環,爲什麼程序不運行for循環(在隊列中插入〜30項)並在此之前退出?多個生產者不能正常工作
import java.util.Date;
import java.util.Deque;
import java.util.concurrent.TimeUnit;
class Event{
Date var;
public Event(Date v){
var = v;
}
}
class WriterTask implements Runnable{
Deque<Event> queue;
int from = 0,to = 0;
public WriterTask(Deque<Event> queue, int from, int to){
this.queue = queue;
this.from = from;
this.to = to;
}
@Override
public void run(){
for(int i=from;i<to;i++){
Event ev = new Event(new Date());
System.out.println("Generating event number: "+i);
queue.addFirst(ev);
try{
System.out.println("SLeeping now:"+Thread.currentThread().getName());
TimeUnit.SECONDS.sleep(1);
}catch(InterruptedException ie){
System.out.println("Interrupted the thread!");
}
}
}
}
class CleanerTask implements Runnable{
Deque<Event> queue;
public CleanerTask(Deque<Event> queue){
this.queue = queue;
}
@Override
public void run(){
while(true){
Date dt = new Date();
clean(dt);
}
}
public void clean(Date date){
// System.out.println("Cleaning for date, current size of queue:"+queue.size());
long difference = 0;
boolean anythingDeleted = false;
do{
if(queue.isEmpty()){return;}
Event first = queue.getLast();
difference = date.getTime() - first.var.getTime();
if(difference > 5000){
queue.removeLast();
anythingDeleted = true;
}
}while(difference>5000);
if(anythingDeleted){
System.out.println("Queue cleaned up, new size:"+queue.size());
}
}
}
測試:
import org.junit.Test;
import org.junit.rules.Timeout;
import java.util.ArrayDeque;
import java.util.Deque;
import java.util.LinkedList;
public class WriterCleanerTest {
@Test
public void consumeCleanTest(){
Deque<Event> queue = new ArrayDeque<Event>();
WriterTask wt = new WriterTask(queue, 0, 10);
Thread wt1 = new Thread(wt);
Thread wt2 = new Thread(new WriterTask(queue, 60, 70));
Thread wt3 = new Thread(new WriterTask(queue, 100, 110));
wt1.start();
wt2.start();
wt3.start();
System.out.println("Size of queue:"+queue.size());
Thread cleanerTask = new Thread(new CleanerTask(queue));
cleanerTask.setDaemon(true);
cleanerTask.start();
}
}
輸出:
Size of queue:0
Final Size of queue:0
Generating event number: 0
Generating event number: 60
SLeeping now:Thread-1
Generating event number: 100
SLeeping now:Thread-2
SLeeping now:Thread-0
Process finished with exit code 0
這正是我最終做的。我的印象是,只要程序中存在活動線程(state = RUNNABLE而不是TERMINATED),它就會繼續運行。感謝你的回答! – 2014-09-04 17:11:01