误解执行人服务 - 我认为



我想启动一组 10 个线程。 在我的主程序构造函数中,我正在使用:

executor = Executors.newFixedThreadPool(NTHREADS);
Callable<String> poller;
for (int i = 0; i < NTHREADS; ++i) {
    Future<String> future = executor.submit(new Poller(0x3A, m_socket, ds_in, ds_out, socketLock));
    set.add(future);
}

对于类 Poller 中的 call() 方法,我有:

public String call()
{
    // This has to be set here, otherwise all threads will have a name of "main".
    myID = Thread.currentThread().getName();
    boolean shutup_loop = true;
    do {
        System.out.println("Hey, I'm thread " + myID);
        System.out.println("Hey, I'm thread " + Thread.currentThread().getName());
        try {
            Thread.sleep(10);
        }
        catch (java.lang.InterruptedException e) {
            System.out.println("thread " + myID + ": " + e);
        }
        // Do if you want the printing to all match up on one line
        synchronized (this) {
            ByteArrayOutputStream baos = SendReceive(pollPacket);
            System.out.print(myID + ": ");
            if (baos != null) {
                printStuff(baos);
                System.out.println();
            }
            notify();
        }
    } while (shutup_loop);
    return "poller is finished";
}
这些 Poller

线程调用 SendReceive(),它是 Poller 类的一部分:

public synchronized ByteArrayOutputStream SendReceive(byte[] toSend)
{
    System.out.println("START");
    System.out.println("SendReceive()1 " + myID);
    System.out.println("SendReceive()2 " + Thread.currentThread().getName());
    System.out.println("END");
    try {
        ds_out.write(toSend, 0, toSend.length);
        ds_out.flush();
    }
    catch (java.io.IOException e) {
        System.out.println("thread " + myID + ": " + e);
    }
    try {
        m_socket.setSoTimeout(200);       // <-- might need tweaking
    }
    catch (java.net.SocketException e) {
        System.out.println("thread " + myID + ": " + e);
    }
    ByteArrayOutputStream baos = null;
    try {
        baos = getResponse(ds_in);
    }
    catch (java.io.IOException e) {
        System.out.println("thread " + myID + ": " + e);
    }
    return baos;
}

因为这是一个同步方法,我希望输出类似于:

START
SendReceive()1 pool-1-thread-1
SendReceive()2 pool-1-thread-1
END
START
SendReceive()1 pool-1-thread-2
SendReceive()2 pool-1-thread-2
END

相反,它正在做:

START
START
START
START
START
START
SendReceive()1 pool-1-thread-2
START
START
START
SendReceive()1 pool-1-thread-6
SendReceive()1 pool-1-thread-7
SendReceive()2 pool-1-thread-2
SendReceive()1 pool-1-thread-3
SendReceive()2 pool-1-thread-6
SendReceive()1 pool-1-thread-1
SendReceive()1 pool-1-thread-9
SendReceive()1 pool-1-thread-8
SendReceive()2 pool-1-thread-9
END
...

什么给?

>synchronized使用this作为锁:在您的情况下,您有多个Poller实例,因此每个实例都使用不同的锁。要使其工作,您需要一个公共锁:

  • 要么使方法static
  • 或使用常用private static final Object lock = new Object();并使用synchronized(lock) {...}

如果您想要在轮询器之间共享套接字,则无需使用执行器服务。无论如何,您都需要序列化套接字的使用,因此您只需循环轮询任务列表并将套接字交给当前套接字即可。

另一方面,如果你真的想使用相同的套接字并行轮询,你的网络协议应该支持这一点,允许你发送轮询消息而不必等待响应;你将有多个请求在传输。但我怀疑这是一个更大、不同的问题,你试图解决什么。

相关内容

  • 没有找到相关文章

最新更新