0

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

首先,我需要迁移一个曾经以这种方式工作的系统:

  1. 一个名为 ServerPool(Thread) 的类使用一个主类进行初始化。
  2. 这个 ServerPool 创建一个队列来接收套接字和一个向量来管理工作线程(S.

所以在池的代码中,我有以下内容:

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 服务它应该返回一个值,所以我考虑使用 Callable、Future 和线程池,但我无法复制完全相同的行为,我尝试实现这一点:

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 将调用服务器池(NewServerPool)的一个新实例,我该如何继续呢?如果有人可以帮助我,我将不胜感激。在此先感谢,最好的问候。

4

2 回答 2

2

有几件事:

首先,您的原始ServerPool类有缺陷,因为它只实例化了SearchThread. 我认为您的意思是从NTHREADS(10)开始SearchThread

接下来,看起来您已经NewSearchThread稍微改变了 from SearchThread- 的方法,因为 for 的构造函数接受NewSearchThread一个SearchQuery参数,而. SearchThreadSearchQueryBlockingQueue

最后,你的NewServerPool类在方法上有所不同,因为它ServerPoolServerPool方法run()不断地将新SearchQuery的 s 放入BlockingQueue. 相比之下,NewServerPool的构造函数接受一个单一的SearchQuery并且什么都不做。

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

public class NewServerPool extends Thread {

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

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

    public void run() {
        while(true){
            SearchQuery client = null;

            if (typeOfQuery == 1) {
                client = new SocketQuery(....);
            } else if (typeOfQuery == 2) {
                client = new StringQuery(...);
            }
            futures.add(executor.submit(new NewSearchThread(client)));
        }
    }
}

请注意,我说“让你开始”......因为上面仍然需要一些补充,例如在run()停止处理请求时正确退出该方法(但这是另一个主题)。

于 2013-05-10T22:16:30.580 回答
2

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

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),但您当然可以更改方法以返回您的规范要求的任何类型。

于 2013-05-14T15:25:31.153 回答