如何为Java并发应用程序制作优化方案?

时间:2013-05-09 21:12:42

标签: java multithreading service web concurrency

我一直在寻找类似的类似问题,但根据我的要求,我认为我需要一些特别的东西,我会详细解释。

首先,我需要迁移过去以这种方式工作的系统:

  1. 一个名为ServerPool(Thread)的类使用主类初始化。
  2. 此ServerPool创建一个队列来接收套接字和一个向量来管理工作线程(S。
  3. 所以在pool的代码中,我有以下内容:

    public class ServerPool extends Thread {
        private LinkedBlockingQueue<SearchQuery> workQueue; //SearchQuery is a Class I defined which can handle two type of processes (for sockets and for single Strings)
        private Vector<SearchThread> workers;
        private final int NTHREADS = 10;
        private int typeOfQuery;
    
        public ServerPool() {
        workers = new Vector<SearchThread>(NUM_THREAD);
        workQueue = new LinkedBlockingQueue<SearchQuery>();
        this.typeOfQuery = typeOfQuery;
        SearchThread search = new SearchThread(workQueue);
        search.start();
        workers.add(search);
    }
    
    public void run() {
        while(true){
        SearchQuery client = null;
    
        if (typeOfQuery == 1) {
            client = new SocketQuery(....);
            } else if (typeOfQuery == 2) {
            client = new StringQuery(...);
            }
            workQueue.put(client);
    }
    }
    

    对于执行该过程的SearchThread:

    public class SearchThread extends Thread {
        private LinkedBlockingQueue<SearchQuery> workQueue = null;
        private SearchQuery request = null;
    
        public SearchThread(LinkedBlockingQueue<SearchQuery> workSource) {
            workQueue = workSource;
        }   
    
        public void run() {
            request = workQueue.take();
            //Here I process the request
            //And use a PrintWriter to give a "response"            
        }
    
    }
    

    这曾经使用带有套接字的telnet工作,但现在我被要求将其转换为Web服务,因此Web Service应该返回一个值,所以我想到使用Callable,Future和Thread Pools ,但我无法复制完全相同的行为,我尝试实现这个:

    public class NewServerPool {
    
        private final int NTHREADS = 10;
        private ExecutorService executor;
        private LinkedBlockingQueue<SearchQuery> workQueue;
        private Vector<Future<String>> futures;
        private boolean end = true;
    
        public NewServerPool(int port, SearchQuery typeOfQuery) {
            executor = Executors.newFixedThreadPool(NTHREADS);
            workQueue = new LinkedBlockingQueue<SearchQuery>();
            futures = new Vector<Future<String>>();
    
        }
    
    
    }
    

    对于搜索线程,现在它是可调用的

    public class NewSearchThread implements Callable<String>{
    
        private SearchQuery searchQuery;
    
        public NewSearchThread(SearchQuery searchQuery) {
            this.searchQuery = searchQuery;
        }
    
        @Override
        public String call() throws Exception {
            String xmlResponse = null;
    
            if (searchQuery == null) {
                throw new InvalidSearchQueryException("The search query is not valid or has null value: " + searchQuery);
            }
    
            if (searchQuery instanceof SocketTimed) {
                System.out.println("It is socket timed query type");
            } else if (searchQuery instanceof WebServiceQuery) {
                System.out.println("It is a web service query type");
            }
    
            xmlResponse = searchQuery.manageResponse();
    
            return xmlResponse;
        }
    

    所以我被困在服务器池中,在这种情况下,我的WebService会调用一个新的Server Pool(NewServerPool)实例,我怎么能继续这个呢?如果有人可以帮助我,我将非常感激。 在此先感谢,最好的问候。

2 个答案:

答案 0 :(得分:2)

有几件事:

首先,您的原始ServerPool类存在缺陷,因为它只会实例化SearchThread的1个实例。我认为你的意思是开始NTHREADS(10)SearchThread s。

接下来,看起来您已经NewSearchThread略微改变SearchThread的方法 - 因为NewSearchThread的构造函数接受SearchQuery参数,而{ {1}}距离SearchThread SearchQuery

最后,您的BlockingQueue课程的方法与NewServerPool的方法不同,因为ServerPool的{​​{1}}方法会不断将新的ServerPool放入run() {1}}。相比之下,SearchQuery的构造函数只需要一个BlockingQueue并且不执行任何操作。

这样的事情怎么样才能让你开始:

NewServerPool

请注意,我说“让你入门”......因为上面仍然需要一些补充,例如在停止接收请求时适当退出SearchQuery方法(但这是另一个主题)。 / p>

答案 1 :(得分:2)

如果你只想“启动”线程池并返回一个值,那么听起来没有任何理由让你的NewServerThreadPool扩展Thread(但不知道完整的规范)你想要实现的目标我不是百分百肯定的。您的启动方法应返回什么类型的值? booleanStringint?你可以尝试这样的事情:

public class NewServerPool {

    private final int NTHREADS = 10;
    private ExecutorService executor;
    private Vector<Future<String>> futures;

    public NewServerPool(int port, SearchQuery typeOfQuery) {
        futures = new Vector<Future<String>>();
    }

    public boolean launchThreadPool() {
        executor = Executors.newFixedThreadPool(NTHREADS);
        return true;
    }

    public void submitToThreadPoolForProcessing(SearchQuery client) {
        futures.add(executor.submit(new NewSearchThread(client)));
    }

    public Vector<Future<String>> getFutures() {
        return futures;
    }
}

请注意,在上面,launchThreadPool()方法的单行内容可以很容易地成为构造函数的一部分(就像在上一篇文章中一样),但是将它分解为自己的方法允许您在启动线程池后返回值。如图所示,它将返回boolean值(总是返回true),但您当然可以更改方法以返回规范要求的任何类型。