问题
I'm trying to write a Java serial device driver and want to use the (new to me) java.util.concurrent
package. I have one method which sends a packet then waits for an ACK. I plan to have char. reception run in a different thread. If the receive thread gets an ACK it should notify the thread with the send packet function. The receive thread implements a state machine and should notify any listeners of decoded packets.
I think I know how to do this using direct Threads, wait
, notify
etc., but am not sure how to do this with the new concurrent package. Would be very grateful for any pointers.
回答1:
Use a CyclicBarrier. Here's a cite of relevance from its Javadoc:
A synchronization aid that allows a set of threads to all wait for each other to reach a common barrier point. CyclicBarriers are useful in programs involving a fixed sized party of threads that must occasionally wait for each other. The barrier is called cyclic because it can be re-used after the waiting threads are released.
So, you need to create a CyclicBarrier
for a number of 2
parties and let the receiver thread invoke await()
after ACK and let the sender thread invoke await()
before doing the SEND.
Here's an SSCCE to get you started.
package com.stackoverflow.q3379797;
import java.util.concurrent.CyclicBarrier;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
public class Test {
public static void main(String[] args) {
CyclicBarrier barrier = new CyclicBarrier(2);
Receiver receiver = new Receiver(barrier);
Sender sender = new Sender(barrier);
ExecutorService executor = Executors.newFixedThreadPool(2);
executor.submit(receiver);
executor.submit(sender);
}
}
class Receiver implements Runnable {
private CyclicBarrier barrier;
public Receiver(CyclicBarrier barrier) {
this.barrier = barrier;
}
@Override
public void run() {
while (true) {
try {
// Wait for ACK (the sleep just simulates that).
Thread.sleep(2000);
System.out.println("ACK");
// Then notify.
barrier.await();
} catch (Exception e) {
e.printStackTrace();
}
}
}
}
class Sender implements Runnable {
private CyclicBarrier barrier;
public Sender(CyclicBarrier barrier) {
this.barrier = barrier;
}
@Override
public void run() {
while (true) {
try {
// Wait for notify.
barrier.await();
// Now do SEND.
System.out.println("SEND");
} catch (Exception e) {
e.printStackTrace();
}
}
}
}
You'll see the following in the stdout:
(2 seconds) ACK SEND (2 seconds) ACK SEND (2 seconds) ACK SEND
来源:https://stackoverflow.com/questions/3379797/java-threaded-serial-port-read-with-java-util-concurrent-thread-access