我正在使用 Account 示例來練習 Java 同步。
這是我的代碼。
賬戶類
class Account {
public int dollars;
public Account(int d) {
dollars = d;
}
// might fail due to concurrently accessing this method
public synchronized void deduct2(int amount) {
dollars -= amount;
}
@Override
public String toString() {
return "" dollars;
}
MyThread 類
class MyThread extends Thread {
static Account account = new Account(10000);
private int id;
public MyThread(int i) {
id = i;
}
@Override
public void run() {
System.out.println("performing my job ....");
for (int i = 0; i < 100; i ) {
account.deduct2(1);
System.out.println("account " account " " getName() "performing....");
}
}
ThreadTest 類
public class ThreadTest {
public static void main(String args[]) {
new ThreadTest().exec();
System.out.println("main finished");
}
private void exec() {
test1();
}
private void test1() {
Thread thread1 = new MyThread(1);
Thread thread2 = new MyThread(2);
Thread thread3 = new MyThread(3);
thread1.start();
thread2.start();
thread3.start();
}}
結果
main finished
performing my job ....
performing my job ....
performing my job ....
account 9997 Thread-0performing....
account 9997 Thread-2performing....
account 9997 Thread-1performing....
account 9995 Thread-2performing....
account 9996 Thread-0performing....
account 9993 Thread-2performing....
account 9994 Thread-1performing....
account 9991 Thread-2performing....
account 9992 Thread-0performing....
account 9989 Thread-2performing....
account 9990 Thread-1performing....
account 9987 Thread-2performing....
account 9988 Thread-0performing....
account 9985 Thread-2performing....
account 9986 Thread-1performing....
....
account 9713 Thread-1performing....
account 9708 Thread-1performing....
account 9709 Thread-0performing....
account 9706 Thread-0performing....
account 9707 Thread-1performing....
account 9704 Thread-1performing....
account 9705 Thread-0performing....
account 9702 Thread-0performing....
account 9703 Thread-1performing....
account 9701 Thread-0performing....
account 9700 Thread-1performing....
我運行了三個不同的新執行緒,每個新執行緒減1一百次。所以賬戶美元的結果是正確的(9700)。
但是我很困惑為什么扣除帳戶美元的程序沒有按我的預期作業。我假設它會像 9999 9998 9997 一樣運行.....
uj5u.com熱心網友回復:
您System.out.println的未同步,例如:
- 在開始的時候dollers為10000,
thread1并thread2執行account.deduct2(1); 現在美元是 9998。 thread3執行account.deduct2(1);現在美元是 9997。thread1然后thread2開始列印account#dollars,你會看到兩個9997。
如果要按順序列印,就放入synchronizedfor回圈。(Account#deduct2不需要再添加synchronized了。):
for (int i = 0; i < 100; i ) {
synchronized (account) {
account.deduct2(1);
System.out.println("account " account " " getName() "performing....");
}
}
轉載請註明出處,本文鏈接:https://www.uj5u.com/ruanti/359322.html
