Create a simple queue with Java threads

前端 未结 4 648
终归单人心
终归单人心 2020-12-17 02:37

I\'m trying to create a simple queue with Java Thread that would allow a loop, say a for loop with 10 iterations, to iterate n (< 10) threads at a time and wait until tho

相关标签:
4条回答
  • 2020-12-17 03:17

    see java.util.concurrent and especially Executors and ExecutorService

    0 讨论(0)
  • 2020-12-17 03:25

    Use the Executors, as recommended by the others. However, if you want the fun of doing it yourself, try something like this. (Take care. I wrote it in Notepad and there's some Exceptions you'll need to catch even if I got everything else right. Notepad's poor at catching coding errors.) This is more a concept than an actual solution to anything, but the idea could be generally useful.

    private ConcurrentLinkedQueue<MyThread>  tQueue =
                 new ConcurrentLinkedQueue<MyThread>();
    
    class MyThread  extends Thread  {
        public Runnable  doSomething;
    
        public void run()  {
            // Do the real work.
            doSomething();
            // Clean up and make MyThread available again.
            tQueue.add( mythread );
            // Might be able to avoid this synch with clever code.
            // (Don't synch if you know no one's waiting.)
            // (But do that later.  Much later.)
            synchronized (tQueue)  {
                // Tell them the queue is no longer empty.
                tQueue.notifyAll();
            }
        }
    }
    

    Elsewhere:

    // Put ten MyThreads in tQueue.
    for (int i = 0; i < 10; i++)  tQueue.add( new MyThread() );
    
    // Main Loop.  Runs ten threads endlessly.
    for (;;)  {
        MyThread  t = tQueue.poll();
        if (t == null)  {
            // Queue empty.  Sleep till someone tells us it's not.
            do  {
                // There's a try-catch combo missing here.
                synchonized( tQueue )  { tQueue.wait() };
                t = tQueue.poll();
            }  while (t == null)  break;  // Watch for fake alert!
        }
        t.doSomething = do_some_work;
        t.start();
    }
    

    Also, note the clever use of ConcurrentLinkedQueue. You could use something else like ArrayList or LinkedList, but you'd need to synchronize them.

    0 讨论(0)
  • 2020-12-17 03:29

    Crate Logger.class :

    public class Logger extends Thread {
        List<String> queue = new ArrayList<String>();
        private final int MAX_QUEUE_SIZE = 20;
        private final int MAX_THREAD_COUNT = 10;
    
        @Override
        public void start() {
            super.start();
            Runnable task = new Runnable() {
                @Override
                public void run() {
                    while (true) {
                        String message = pullMessage();
                        Log.d(Thread.currentThread().getName(), message);
                        // Do another processing
                    }
                }
            };
            // Create a Group of Threads for processing
            for (int i = 0; i < MAX_THREAD_COUNT; i++) {
                new Thread(task).start();
            }
        }
    
        // Pulls a message from the queue
        // Only returns when a new message is retrieves
        // from the queue.
        private synchronized String pullMessage() {
            while (queue.isEmpty()) {
                try {
                    wait();
                } catch (InterruptedException e) {
                }
            }
            return queue.remove(0);
        }
    
        // Push a new message to the tail of the queue if
        // the queue has available positions
        public synchronized void pushMessage(String logMsg) {
            if (queue.size() < MAX_QUEUE_SIZE) {
                queue.add(logMsg);
                notifyAll();
            }
    
        }
    }
    

    Then insert bellow code in your main class :

    Logger logger =new Logger();
    logger.start();
    for ( int i=0; i< 10 ; i++) {
        logger.pushMessage(" DATE : "+"Log Message #"+i);
    }
    
    0 讨论(0)
  • 2020-12-17 03:35

    I would use the Java 5 Executors instead of rolling your own. Something like the following:

    ExecutorService service = Executors.newFixedThreadPool(10);
    // now submit our jobs
    service.submit(new Runnable() {
        public void run() {
            do_some_work();
        }
    });
    // you can submit any number of jobs and the 10 threads will work on them
    // in order
    ...
    // when no more to submit, call shutdown, submitted jobs will continue to run
    service.shutdown();
    // now wait for the jobs to finish
    service.awaitTermination(Long.MAX_VALUE, TimeUnit.NANOSECONDS);
    
    0 讨论(0)
提交回复
热议问题