如何使用Hazelcast制作多线程应用程序

时间:2014-12-09 11:58:47

标签: java multithreading queue pool hazelcast

我正在为我的毕业设计开发一个项目。我正在使用免费版的Hazelcast,所以我无法请求支持帮助。

我编写了一个适用于单台计算机的java应用程序。我使用LinkedList作为队列,并有一个由5个工作线程组成的池。工作线程只从队列中取出一个作业并执行它。

工作代码:

package com.stackoverflow.multithread.app;

import java.util.Date;

/**
 * Job
 */
public class Job implements Runnable {

    private final Object req;
    private final long createTime = new Date().getTime();

    public Job(Object req) {
        this.req = req;
    }

    public boolean isPoison() {
        return req == null;
    }

    public long getWaitTime(){
        return new Date().getTime() - createTime;
    }

    @Override
    public void run() {
        try {
             //Do the job
        } catch (Exception e){
            e.printStackTrace();
        }
    }
}

工作队列代码

package com.stackoverflow.multithread.app;

import java.util.ArrayList;
import java.util.LinkedList;
import java.util.List;

/**
 * WorkQueue
 */
public class WorkQueue {

    private static int minThreads;
    private static int maxThreads;
    private static final List<PoolWorker> threads = new ArrayList<PoolWorker>();
    private static final LinkedList queue = new LinkedList();
    private static WorkQueue instance = null;

    /**
     * WorkQueue
     */
    protected WorkQueue() {
        minThreads = 1;
        maxThreads = 5;

        for (int i = 0; i < minThreads; i++) {
            PoolWorker worker = new PoolWorker();
            threads.add(worker);
            worker.start();
        }
    }

    /**
     * getInstance
     *
     * @return Singleton WorkQueue instance
     */
    public static WorkQueue getInstance() {
        if (instance == null) {
            instance = new WorkQueue();
        }
        return instance;
    }

    /**
     * clone
     *
     * @return null
     * @throws CloneNotSupportedException: Singleton class can not be cloned.
     */
    @Override
    public WorkQueue clone() throws CloneNotSupportedException {
        throw new CloneNotSupportedException("Singleton class can not be cloned.");
    }

    public void execute(Job r) {
        synchronized (queue) {
            queue.addLast(r);
            manageWorkers();
            queue.notify();
        }
    }

    private void manageWorkers(){
        while ((queue.size() / 2 > threads.size() || (queue.size() > 0 && ((Job)queue.peekFirst()).getWaitTime() > 1000)) && threads.size() < maxThreads){
            PoolWorker worker = new PoolWorker();
            threads.add(worker);
            worker.start();
        }
        if (queue.size() < threads.size() && threads.size() > minThreads){
            execute(new Job(null)); //poison
        }
    }

    private class PoolWorker extends Thread {

        @Override
        public void run() {
            Job r;

            while (true) {
                synchronized (queue) {
                    while (queue.isEmpty()) {
                        try {
                            queue.wait();
                        } catch (InterruptedException ignored) {
                        }
                    }

                    r = (Job) queue.removeFirst();
                    manageWorkers();
                    if (r.isPoison()) {
                        break;
                    }
                }
                // If we don't catch RuntimeException, 
                // the pool could leak threads
                try {
                    r.run();
                } catch (RuntimeException e) {
                    e.printStackTrace();
                } catch (ExceptionInInitializerError e){
                    e.printStackTrace();
                } catch (Exception e){
                    e.printStackTrace();
                } 
            }
            threads.remove(this);
        }
    }
}

现在我想在主动 - 主动群集上进行此工作,并希望使用HazelCast(v3.3),以确保每个和所有作业应该只执行一次,即使其中一台计算机出现故障。

我检查了ExecutorService,但它逐个执行作业(单线程)。我无法找到一个很好的解决方案来做到这一点。人们提到ParallelExecutorService但它在这个版本中不可用,或者它不是免费版的一部分。

请注意,我不必使用Hazelcast执行此操作。任何免费的解决方案都很好。

有什么建议吗?

1 个答案:

答案 0 :(得分:0)

为什么不使用实现Executor(Service)接口的IExecutorService。所以你可以在那里抛出一个任务(确保它是可序列化的),集群中的任何成员都可以接受该任务来处理它。

无需乱搞自己的线程池。

以下是您可以查看的一组示例: https://github.com/hazelcast/hazelcast-code-samples/tree/master/distributed-executor