我想开始一组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) {...}
  • 09-25 21:23