我想启动一组 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) {...}
如果您想要在轮询器之间共享套接字,则无需使用执行器服务。无论如何,您都需要序列化套接字的使用,因此您只需循环轮询任务列表并将套接字交给当前套接字即可。
另一方面,如果你真的想使用相同的套接字并行轮询,你的网络协议应该支持这一点,允许你发送轮询消息而不必等待响应;你将有多个请求在传输。但我怀疑这是一个更大、不同的问题,你试图解决什么。