这个代码取自书本
Java线程和并发实用程序
Jeff Friesen:
public class PC {
public static void main(String[] args) {
Shared s = new Shared();
new Producer(s).start();
new Consumer(s).start();
}
}
class Shared {
private char c;
private volatile boolean writeable = true;
synchronized void setSharedChar(char c) {
while (!writeable)
try {
wait();
} catch (InterruptedException ie) {
}
this.c = c;
writeable = false;
notify();
}
synchronized char getSharedChar() {
while (writeable)
try {
wait();
} catch (InterruptedException ie) {
}
writeable = true;
notify();
return c;
}
}
class Producer extends Thread {
private final Shared s;
Producer(Shared s) {
this.s = s;
}
@Override
public void run() {
for (char ch = 'A'; ch <= 'Z'; ch++) {
synchronized(s) {
s.setSharedChar(ch);
System.out.println(ch + " produced by producer.");
}
}
}
}
class Consumer extends Thread {
private final Shared s;
Consumer(Shared s) {
this.s = s;
}
@Override
public void run() {
char ch;
do {
synchronized(s) {
ch = s.getSharedChar();
System.out.println(ch + " consumed by consumer.");
}
} while (ch != 'Z');
}
}
我不明白为什么有必要
volatile
这个
writeable
字段,因为它只能由访问
synchronized
方法,其效果与volatile相同(可见性+写入互斥)。以及为什么字段
可写的
需要
不稳定的
而不是字段
c
在这种情况下。
下一个代码也有同样的问题
balance
字段:为什么它需要是可变的,因为它已经被访问了
同步的
withdraw
方法
public class CheckingAccount {
private volatile int balance;
public CheckingAccount(int initialBalance) {
balance = initialBalance;
}
public synchronized boolean withdraw(int amount) {
if (amount <= balance) {
try {
Thread.sleep((int) (Math.random() * 200));
} catch (InterruptedException ie) {
}
balance -= amount;
return true;
}
return false;
}
public static void main(String[] args) {
final CheckingAccount ca = new CheckingAccount(100);
Runnable r = new Runnable() {
@Override
public void run() {
String name = Thread.currentThread().getName();
for (int i = 0; i < 10; i++)
System.out.println (name + " withdraws $10: " +
ca.withdraw(10));
}
};
Thread thdHusband = new Thread(r);
thdHusband.setName("Husband");
Thread thdWife = new Thread(r);
thdWife.setName("Wife");
thdHusband.start();
thdWife.start();
}
}
有人能解释一下吗?