0

I have a worker threadpool set up that executes a bit of work which I want to log in a central place.

To be more precise, I've extended the Thread class into a worker class, which checks the status of a concurrent queue. If it's empty, then it waits. As elements are added by another thread, notify() wakes the workers. Once they've completed the task, they wait for the next element in the queue.

What's the best practice to have each of the threads report their status at the end of each of their tasks?

public class PoolWorker extends Thread {

public ConcurrentLinkedQueue<Device> q;

public PoolWorker(ConcurrentLinkedQueue<Device> q, String type){
    this.q = q;         
    this.type = type;
}

@Override 
public void run(){
    while (true)
    {
        Device d = null;
        try{
            synchronized(q){
                while(q.isEmpty())
                {
                    q.wait(); // wait for a notify()
                }
                d = q.remove();

            }
                            // do some work
                            // report status of work completed 
             }
}
CodeOcelot
  • 3,403
  • 3
  • 22
  • 23
  • Could you post your code so that we can help you? Could you explain more precisely _"report their status"_? – xav Mar 21 '14 at 22:01
  • 1
    And why don't you use a `BlockingQueue`? – fge Mar 21 '14 at 22:03
  • Also, "What's the best practice to have each of the threads report their status at the end of each of their tasks?" <-- to whom? – fge Mar 21 '14 at 22:04
  • 2
    You should be using `ExecutorService` classes and not do your own pool. You could submit some sort of wrapped runnable so as each job finishes, the wrapping runnable logs something. – Gray Mar 21 '14 at 22:16

2 Answers2

0

As mentioned best way is to use BlockingQueue. Below is the sample code:

public class PoolWorker extends Thread {
    public ArrayBlockingQueue<String> q;
    public String type;

    public PoolWorker(ArrayBlockingQueue<String> q, String type) {
        this.q = q;
        this.type = type;
    }

    @Override
    public void run() {
        while(true){
            String work = null;
            try {
                System.out.println("PoolWorker.run:waiting .............");
                work = q.take();
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            System.out.println("PoolWorker.run..work: " + work);
        }

    }

    public static void main(String[] args) throws InterruptedException {
        ArrayBlockingQueue<String> pool = new ArrayBlockingQueue<String>(100);
        PoolWorker worker = new PoolWorker(pool, "Something");

        worker.start();
        addWork(pool, "work1");
        addWork(pool, "work2");
        addWork(pool, "work3");
        addWork(pool, "work4");
        addWork(pool, "work5");
        //Just give enough time to run
        Thread.sleep(5000);
    }


    private static void addWork(ArrayBlockingQueue<String> pool, String work) throws InterruptedException {
        System.out.println("PoolWorker.addWork: " + work);
        pool.put(work);
    }
}

There is nice sample code available in Java documentation as well: http://docs.oracle.com/javase/7/docs/api/java/util/concurrent/BlockingQueue.html

Mak
  • 596
  • 5
  • 10
0

Try to do something like this

ExecutorService exec = Executors.newFixedThreadPool(10);
    Runnable runn = new Runnable() 
    {
        @Override
        public void run() 
        {
            System.out.println("");
        }
    };
    exec.execute(runn);
Sri777
  • 530
  • 3
  • 9