如何使用LinkedBlockingQueue来运行任务

时间:2015-02-12 14:59:48

标签: java threadpool blockingqueue

我目前正试图让我的代码使用simpleTesting中的代码打印simpleTask方法中的内容20次。想法是simpleTesting将20个simpleTask实例添加到队列中,然后从simplePoolThread中的队列中取出它们。应该发生的是它打印出测试消息20次然后继续运行,同时从队列中寻找更多的东西(但没有)。相反,它目前只是不打印任何东西并持续运行。这是我的代码(很多是接口,我相信问题在于simpleThreadPool代码):

package simpleThreadPool;

/**
 *   <<-- Pool Thread -->> 
 *
 *   It will be running continuously. It will try to retrieve new tasks when it is idle. 
 */
public interface ISimplePoolThread extends Runnable {
    /**
     *   Use an infinite loop to retrieve and perform tasks.
     */
    @Override
    public void run();
}

package simpleThreadPool;

/**
 *   <<-- Simple Task -->> 
 *
 *   ISimpleTask is to be performed by PoolThread. 
 */
public interface ISimpleTask{
    /**
     *   #1. Create a class to implement ISimpleTask, put content of the task to method run().
     */
    public void run();
}

    package simpleThreadPool;


    /**
     *   <<-- Thread Pool -->> 
     *   It manages a queue of tasks, starts some pool threads.
     *      
     *   #1. Create a task queue by using queue data structures, or designing your own data structure. 
     */
    public interface ISimpleThreadPool {

        /**
         *   #1. Initialize your queue (or do so in somewhere)
         *   #2. Starts some ISimplePoolThreads.
         */
        public void start();

        /**
         *   #1. Stops everything
         */
        public void stop();

        /**
         *   #1. Add a task to your queue.
         */
        public void addTask(ISimpleTask task);
    }

    package simpleThreadPool;

public class SimpleTask implements ISimpleTask {

    @Override
    public void run() {
        System.out.println("testing testing 1 2 3");
    }
}

。 我认为问题在于这段代码,其中任务是从队列中获取的:

package simpleThreadPool;

import java.util.concurrent.LinkedBlockingQueue;

public class SimplePoolThread implements ISimplePoolThread, Runnable {


    private LinkedBlockingQueue<ISimpleTask> queue = new LinkedBlockingQueue<>();

    @Override
    public void run() {

        while(true) {
            System.out.println("Inserting Element: ");
            try {
                queue.take();
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }


}

package simpleThreadPool;

import java.util.concurrent.LinkedBlockingQueue;

public class SimpleThreadPool implements ISimpleThreadPool {

    private LinkedBlockingQueue<ISimpleTask> queue = new LinkedBlockingQueue<>();

    @Override
    public void start() {
        (new Thread(new SimplePoolThread())).start();
    }

    @Override
    public void stop() {
        try {
            queue.take();
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }

    @Override
    public void addTask(ISimpleTask task) { 

        try {
            queue.put(task);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }
}

测试文件:

package simpleThreadPool;

public class SimpleTesting implements ISimpleTask{

    private int i;

    public SimpleTesting(int i){
        this.i = i;
    }

    @Override
    public void run() {
        System.out.println(i);
    }

    public static void main(String args[]){
        // Initialize thread pool
        SimpleThreadPool pool = new SimpleThreadPool();
        pool.start();
        // Create 20 tasks
        for(int i = 1; i<=20; i++){
            pool.addTask(new SimpleTesting(i));
        }
    }
}

1 个答案:

答案 0 :(得分:0)

SimplePoolThread中的任务队列是阻塞队列。一旦启动它就会执行queue.take()。 Take是一个阻塞操作。线程坐在那里永远等待,直到其他东西将任务添加到队列中。

你在问题​​所在地的预感非常接近。问题是SimplePoolThread中的队列和SimpleThreadPool中的队列不一样;你有两个独立的队列。因此,当SimpleTesting添加任务时,它们会进入Pool的队列而不会进入Thread的队列。所以线程将永远坐在那里等待什么。你也忘了在SimplePoolThread中实际运行你的任务。

请尝试以下方法。

public class SimpleThreadPool implements ISimpleThreadPool {

private LinkedBlockingQueue<ISimpleTask> queue = new LinkedBlockingQueue<>();

@Override
public void start() {
    (new Thread(new SimplePoolThread(queue))).start();
}

请注意,池中的队列已传递到线程中。然后该线程保持对此队列的引用。在线程的运行()期间,它现在也实际运行任务。

public class SimplePoolThread implements ISimplePoolThread, Runnable {


private LinkedBlockingQueue<ISimpleTask> queue;

public SimplePoolThread(LinkedBlockingQueue<ISimpleTask> queue)
{
    this.queue = queue;
}

@Override
public void run() {

    while(true) {
        System.out.println("Inserting Element: ");
        try {
            ISimpleTask task = queue.take();
            task.run();
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }
}

这是输出:

Inserting Element: 
1
Inserting Element: 
2
Inserting Element: 
3

...等。

我认为这是为了做作业,否则我会告诉你不要重新发明轮子并使用Java的内置池服务。

http://docs.oracle.com/javase/7/docs/api/java/util/concurrent/package-summary.html