1. Resource sharing:
ReentrantLock/Condition/await/signal
public class Exchanger {
private String message = null;
private boolean empty = true;
private Object lock = new Object();
public void push(String message) {
synchronized (lock) {
try {
while (!empty) {
try {
lock.wait();
} catch
(InterruptedException e) {
e.printStackTrace();
}
}
this.message = message;
this.empty = false;
} finally {
lock.notifyAll();
}
}
}
public String pull() {
synchronized (lock) {
try {
while (empty) {
try {
lock.wait();
} catch
(InterruptedException e) {
e.printStackTrace();
}
}
final String result = message;
this.message = null;
this.empty = true;
return result;
} finally {
lock.notifyAll();
}
}
}
public static void main(String[] args) {
final Exchanger exchanger = new Exchanger();
final String[] stringArray = new String[] { "a", "b", "c", "d", "e", "f" };
new Thread(() -> {
for (String str : stringArray) {
exchanger.push(str);
}
System.out.println("push
EXIT");
}).start();
new Thread(() -> {
int i = 0;
final int size = stringArray.length;
do {
i++;
String result = exchanger.pull();
System.out.println("" + i + ":" + result);
} while (i < size);
System.out.println("pull
EXIT");
}).start();
}
}
|
object wait/notifyAll
public class Exchanger2 {
private String message = null;
private boolean empty = true;
private Lock lock = new ReentrantLock();
private Condition messageReady = lock.newCondition();
public void push(String message) {
lock.lock();
try {
while (!empty) {
try {
messageReady.await();
} catch
(InterruptedException e) {
e.printStackTrace();
}
}
this.message = message;
this.empty = false;
messageReady.signal();
} finally {
lock.unlock();
}
}
public String pull() {
lock.lock();
try {
while (empty) {
try {
messageReady.await();
} catch
(InterruptedException e) {
e.printStackTrace();
}
}
final String result = message;
this.message = null;
this.empty = true;
messageReady.signal();
return result;
} finally {
lock.unlock();
}
}
public static void main(String[] args) {
final Exchanger2 exchanger = new Exchanger2();
final String[] stringArray = new String[] { "a", "b", "c", "d", "e", "f" };
new Thread(() -> {
for (String str : stringArray) {
exchanger.push(str);
}
System.out.println("push
EXIT");
}).start();
new Thread(() -> {
int i = 0;
final int size = stringArray.length;
do {
i++;
String result = exchanger.pull();
System.out.println("" + i + ":" + result);
} while (i < size);
System.out.println("pull
EXIT");
}).start();
}
}
|
2. Synchronization between two actions
public class JavaReentrantLock
{
private static final Lock lock1 = new ReentrantLock();
private static final Lock lock2 = new ReentrantLock();
private static int counter = 0;
private static Random random = new Random();
private static final CountDownLatch latchStartLatch = new CountDownLatch(1);
private static final CountDownLatch latchGroupLatch = new CountDownLatch(2);
public static void main(String[] args) {
final Thread thread1 = new Thread(() -> {
System.out.println("action1
starting...");
action1();
});
final Thread thread2 = new Thread(() -> {
System.out.println("action2
starting...");
action2();
});
latchStartLatch.countDown();
thread1.start();
thread2.start();
while (true) {
try {
latchGroupLatch.await();
break;
} catch
(InterruptedException e) {
e.printStackTrace();
}
}
}
private static void println(final String value) {
counter++;
System.out.println("value(" + counter + "):" + value);
if (counter >= 100) {
System.exit(0);
}
}
private static void action1() {
while (true) {
try {
latchStartLatch.await();
break;
} catch
(InterruptedException e) {
e.printStackTrace();
}
}
latchGroupLatch.countDown();
while (true) {
lock1.lock();
try {
lock2.lock();
try {
println("action1");
} finally {
lock2.unlock();
}
try {
TimeUnit.MICROSECONDS.sleep(random.nextInt(1000));
} catch
(InterruptedException e) {
e.printStackTrace();
}
} finally {
lock1.unlock();
}
try {
TimeUnit.MICROSECONDS.sleep(random.nextInt(1000));
} catch
(InterruptedException e) {
e.printStackTrace();
}
}
}
private static void action2() {
while (true) {
try {
latchStartLatch.await();
break;
} catch
(InterruptedException e) {
e.printStackTrace();
}
}
while (true) {
lock2.lock();
try {
lock1.lock();
try {
println("action2");
} finally {
lock1.unlock();
}
try {
TimeUnit.MICROSECONDS.sleep(random.nextInt(1000));
} catch
(InterruptedException e) {
e.printStackTrace();
}
} finally {
lock2.unlock();
}
try {
TimeUnit.MICROSECONDS.sleep(random.nextInt(1000));
} catch
(InterruptedException e) {
e.printStackTrace();
}
}
}
}
|