Problem: I have to manage a post office with two queue, one is managed by the programmer(the first queue), the other is implicit in the ThreadPool. So, each thread has to pass in the first queue, then in the second, then should be executed. I have a solution, but the problem is that threads are executed only after all of them are inserted in the first queue. I think it is logically right to have a little few thread in the queue, and others which are executed meanwhile. This is the (wrong) solution find by me. Tasks are modelled with class Task which implements Runnable. The thradPool is nother class called UfficioPostale, then there is First with main.
import java.util.concurrent.*;
import java.lang.*;
import java.util.*;
class Task implements Runnable{
public int id;
public Task(int id){
this.id=id;
}
public void run(){
int delay = ThreadLocalRandom.current().nextInt(0, 50 + 1);
try {
Thread.sleep(delay);
System.out.printf("Persona %d: eseguita\n",this.id);
}
catch (InterruptedException e) {
System.err.println("Interruzione su sleep.");
}
System.out.printf("Persona %d: uscita da sportello\n", this.id);
}
}
class UfficioPostale{
private ThreadPoolExecutor pool;
private ArrayBlockingQueue<Runnable> q;
//TODO:controllo su parametri funzioni
public UfficioPostale(int numSportelli,int dimq){
q = new ArrayBlockingQueue<Runnable>(dimq);
pool = new ThreadPoolExecutor(numSportelli,numSportelli,60L,TimeUnit.MILLISECONDS,q);
}
public void executeTask(Task t){
//TODO: controlli su parametri
pool.execute(t);
}
public int sizeq(){
return q.size();
}
public void close(){
pool.shutdown();
}
}
public class First{
public static void main(String[] args){
int numSportelli = 4; //number of core
int dimq = 10; //dim second queue(the one in threadPool)
int k = 50; //dim first queue
LinkedBlockingQueue<Task> q1 = new LinkedBlockingQueue<Task>(k); //prima coda esterna
UfficioPostale p = new UfficioPostale(numSportelli, dimq);
//Assumo che la dimensione della coda esterna sia maggiore della dimensione della coda interna
int numThread = 50;
int i = 1;
while(numThread >= 0){
Task t = new Task(i);
try{
q1.put(t);
System.out.println("Task "+i+" inserted in queue 1");
}catch(Exception e){
System.out.println("queue 1 full");
}
//se la seconda coda ha spazio e se la prima non e' vuota, allora mando il thread alla seconda coda, pii' vicina allo sportello
if(p.sizeq()<10 && q1.isEmpty() == false){
try{
//prendo l'elemento dalla coda esterna e lo eseguo, permettendo al pool di gestire la coda interna come opportuno
p.executeTask(q1.take());
}catch (Exception e) {
System.out.println("full queue");
}
}
numThread--;
i++;
}
//Se ci sono ancora task in attesa nella prima coda, li trasfrisco nella seconda
while(q1.isEmpty() == false) {
if (p.sizeq()<10) {
try {
p.executeTask(q1.take());
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
//chiudo il pool
p.close();
}
}
Cutted output is this. Threads starts to 1 from 50, all terminate