我正在尝试创建一个系统,其中一个线程A将项添加到缓冲区,然后另一个线程B负责按照它们输入的确切顺序读取项,然后对它们执行一些可能很长的操作。
我最好的猜测:
Class B extends Thread {
Buffer fifo = BufferUtils.synchronizedBuffer(new BoundedFifoBuffer());
add(Object o) { // Thread A calls me, and doesn't deal well with delays :)
fifo.add(o); // will the sync below prevent this from happening?
// or can .add be independent of the sync ?
}
run() {
synchronized (fifo) { // why am i sync'd here? I am the only thread accessing...
while ( item in buffer ) { // also how do i check this, and block otherwise?
process(fifo.remove());
}
}
|
}
如您所见,我甚至不确定是否需要同步。我遇到的线程安全问题与get()访问无关,因为只有一个线程访问它,但大多数重要的是线程A调用.add()而没有任何在线程B处理缓冲区内容期间的并发访问异常。
也许我在想这个?和她一起安全吗?非常感谢您对此问题的评估。
此致
杰
答案 0 :(得分:2)
如果我没有错,你也可能对这个ArrayBlockingQueue课感兴趣。
答案 1 :(得分:1)
如果您有用于记录的字符流,则最快的方法可能是使用管道。
PipedOutputStream pos = new PipedOutputStream();
final PipedInputStream pis = new PipedInputStream(pos, 256*1024);
ExecutorService es = Executors.newSingleThreadExecutor();
es.execute(new Runnable() {
@Override
public void run() {
byte[] bytes = new byte[256*1024];
int length;
try {
while ((length = pis.read(bytes)) > 0) {
// something slow.
Thread.sleep(1);
}
} catch (Exception e) {
e.printStackTrace();
}
}
});
// time latency
PrintWriter pw = new PrintWriter(pos);
long start = System.nanoTime();
int runs = 10*1000*1000;
for(int i=0;i<runs;i++) {
pw.println("Hello "+i);
}
long time = System.nanoTime() - start;
System.out.printf("Took an average of %,d nano-seconds per line%n", time/runs);
es.shutdown();
打印
Took an average of 269 nano-seconds per line
注意:管道本身不会产生任何垃圾。 (与队列不同)
您可以使用ExecutorService来包装队列和线程
ExecutorService es =
es.submit(new Runnable() {
public void run() {
process(o);
}
});