我在閱讀Oracle提供的官方Java Tutorial,我想將我的知識付諸實踐。如何在java中使用內部鎖?
我想看Thread Interference的行動和使用Intrinsic Locks and Synchronization解決它。所以,我創建了一個名爲Counter的類:
- 兩個字段都被初始化爲0
- 方法遞增和遞減它們的值。
- 打印出值的方法。
。
public class Apple {
public static void main(String[] args) {
Counter myCounter = new Counter();
Thread a = new Thread(myCounter);
Thread b = new Thread(myCounter);
a.start();
b.start();
}
}
class Counter implements Runnable {
public int a = 0;
public int b = 0;
void incA() {
++a;
}
void decA() {
--a;
}
void incB() {
++b;
}
void decB() {
--b;
}
void printValues() {
System.out.println("a: " + a + " | b: " + b);
}
public void run() {
for (int i = 0; i < 10; i++) {
incA();
decA();
incB();
decB();
printValues();
try {
Thread.sleep(1);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
首先,我運行我的程序時未使用內部鎖或同步,輸出是我期望的線程干擾。
...
a: 0 | b: 0
a: 0 | b: 1
a: 0 | b: 0
a: 1 | b: 0
a: 0 | b: 0
...
現在我想整理使用內部鎖定此問題,以便當一個線程遞增或遞減一個,另一個線程可以在同一時間改變B,而不是使用synchronized方法這將阻止。
所以我使用內部鎖添加了兩個新字段(鎖)和同步塊。這裏是新的代碼:
class Counter implements Runnable {
public int a = 0;
public int b = 0;
Object lock1 = new Object();
Object lock2 = new Object();
void incA() {
synchronized (lock1) {
++a;
}
}
void decA() {
synchronized (lock1) {
--a;
}
}
void incB() {
synchronized (lock2) {
++b;
}
}
void decB() {
synchronized (lock2) {
--b;
}
}
void printValues() {
System.out.println("a: " + a + " | b: " + b);
}
public void run() {
for (int i = 0; i < 10; i++) {
incA();
decA();
incB();
decB();
printValues();
try {
Thread.sleep(1);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
我沒有做任何改變的主要方法,所以我沒有包括它。但是我跑這個代碼三次,這是最後一次嘗試輸出:
...
a: 0 | b: 0
a: 0 | b: 0
a: 0 | b: 1
a: 0 | b: 0
我做了什麼錯?代碼應該如何?
我只是想要一個簡單的示例代碼,使用內部鎖。
你的輸出有什麼問題?對我來說它看起來正確。 –
另外爲什麼你需要'myCounter.printValues();'在你的主要方法? – theo
@theo對不起,我從以前的嘗試離開它。 –