Skip to content

Instantly share code, notes, and snippets.

@westhood
Last active August 29, 2015 14:04
Show Gist options
  • Select an option

  • Save westhood/438540edd3d6d1c26349 to your computer and use it in GitHub Desktop.

Select an option

Save westhood/438540edd3d6d1c26349 to your computer and use it in GitHub Desktop.
package puzzle;
import java.util.ArrayList;
import java.util.concurrent.locks.ReentrantLock;
public abstract class Buffer<T> {
private ArrayList<T> _items = null;
private ArrayList<T> _prepare = null;
ReentrantLock _gate = new ReentrantLock();
public void Add(T item) {
_gate.lock();
try {
if (_items == null) {
_items = new ArrayList<T>();
}
_items.add(item);
} finally {
_gate.unlock();
}
}
public abstract void FlushItem(T item);
public void Flush() {
ArrayList<T> items;
_gate.lock();
try {
items = _prepare;
_prepare = null;
} finally {
_gate.unlock();
}
if (items != null) {
for (T item: items) {
FlushItem(item);
}
}
}
public void Prepre() {
_gate.lock();
try {
if (_prepare != null) {
throw new RuntimeException("last prepre is not flushed");
}
_prepare = _items;
_items = null;
} finally {
_gate.unlock();
}
}
public static class Item {
private int count = 2;
private int seq;
public Item(int n) {
seq = n;
}
public void First() {
if (count != 2) {
throw new RuntimeException(String.format("expected 2 got %d", count));
}
count--;
}
public void Second() {
if (count != 1) {
throw new RuntimeException(String.format("expected 1 got %d", count));
}
count--;
System.out.format("item:%d done\n", seq);
}
}
public static void main(String[] args) throws InterruptedException {
final Buffer<Item> first = new Buffer<Item>() {
@Override
public void FlushItem(Item item) {
item.First();
}
};
final Buffer<Item> second = new Buffer<Item>() {
@Override
public void FlushItem(Item item) {
item.Second();
}
};
Thread t1 = new Thread(new Runnable() {
@Override
public void run() {
int n = 0;
while (true) {
Item item = new Item(n);
n++;
first.Add(item);
second.Add(item);
try {
Thread.sleep(1);
} catch (InterruptedException e) {
}
}
}
});
t1.start();
Thread t2 = new Thread(new Runnable() {
@Override
public void run() {
while (true) {
second.Prepre();
first.Prepre();
first.Flush();
second.Flush();
try {
Thread.sleep(10);
} catch (InterruptedException e) {
}
}
}
});
t2.start();
t2.join();
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment