我想开始一组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
...
是什么给出了?
答案 0 :(得分:2)
synchronized
使用this
作为锁:在您的情况下,您有几个Poller
个实例,因此每个实例使用不同的锁。为了使它工作,你需要一个共同的锁:
static
private static final Object lock = new Object();
并使用synchronized(lock) {...}
答案 1 :(得分:0)
如果你所追求的是在轮询器之间共享套接字,则不需要使用执行程序服务。您无论如何都需要序列化套接字的使用,因此您可以循环遍历轮询任务列表并将当前套接字交给套接字使用。
另一方面,如果你真的想要使用相同的套接字并行轮询,你的网络协议应该支持你,允许你发送一个轮询消息,而不必等待它的响应;你会有多个飞行请求。但我怀疑你要解决的问题是一个更大而且更不同的问题。