Joseph Haugh
University of New Mexico
public class SynchronizedCounter {
private int c = 0;
public synchronized void increment() { c++; }
public synchronized int value() { return c; }
}
private Point p;
...
public void copyP(Point destination) {
synchronized(p) {
destination.x = p.x;
destination.y = p.y;
}
}
public void addP(int n) {
synchronized(p) {
p.x += n;
p.y += n;
}
}
Both synchronized blocks obtain lock on member variable p
synchronized(this) blockpublic class FibWorker extends Thread {
private final String name;
private long step = 0;
private int x = 0;
private int y = 1;
private int z;
private boolean keepGoing = true;
public FibWorker(String name) {
this.name = name;
z = x + y;
}
private synchronized void update() {
step++;
if (z < 0) {
// restart after overflow
x = 0;
y = 1;
} else {
x = y;
y = z;
}
z = x + y;
}
public void quit() {
keepGoing = false;
}
@Override
public void run() {
while(keepGoing) {
update();
}
System.out.println(name +
" stopping at step " + step);
}
@Override
public synchronized String toString() {
return name + " step " + step +
", x = " + x + ", y = " + y + ", z = " + z;
}
static void main() throws InterruptedException {
FibWorker[] workers = new FibWorker[]{ new FibWorker("A"), new FibWorker("B") };
for(FibWorker fibWorker : workers) { fibWorker.start(); }
for(int i = 0; i < 10; ++i) {
System.out.println("i = " + i);
for(FibWorker fibWorker : workers) {
System.out.println(fibWorker);
}
Thread.sleep(1000); // Take a short nap
}
for(FibWorker fibWorker : workers) { fibWorker.quit(); }
for(FibWorker fibWorker : workers) {
// wait until this thread has finished.
fibWorker.join();
}
System.out.println("All workers are done. Goodbye.");
}
}
update and toString methods are synchronizedjava.util.concurrent.BlockingQueue interface extends java.util.Queue with methods that make current thread wait if necessary.
public class Producer implements Runnable {
private final String name;
private final BlockingQueue<Integer> queue;
public Producer(String name, BlockingQueue<Integer> queue) {
this.name = name;
this.queue = queue;
}
@Override
public void run() {
System.out.println("Start " + name);
try {
for(int i = 0; i < 20; i++) {
System.out.println(name + " produces " + i);
queue.put(i);
}
System.out.println(name + " is done producing");
} catch (InterruptedException e) {
System.out.println(name + " was interrupted");
}
}
}
public class Consumer implements Runnable {
private final String name;
private final BlockingQueue<Integer> queue;
public Consumer(String name, BlockingQueue<Integer> queue) {
this.name = name;
this.queue = queue;
}
@Override
public void run() {
System.out.println("Start " + name);
try {
while(true) {
int value = queue.take();
System.out.println(name + " consumes " + value);
}
} catch (InterruptedException e) {
System.out.print(name + " was interrupted");
}
}
}
static void main() {
BlockingQueue<Integer> sharedQueue =
new LinkedBlockingQueue<>();
Thread prodThread =
new Thread(new Producer("P", sharedQueue));
Thread consThread =
new Thread(new Consumer("C", sharedQueue));
prodThread.start();
consThread.start();
}