以下代碼顯示了如何在程序中運(yùn)行多線程。
public class Main {
public static void main(String[] args) {
// Create two Thread objects
Thread t1 = new Thread(Main::print);
Thread t2 = new Thread(Main::print);
// Start both threads
t1.start();
t2.start();
}
public static void print() {
for (int i = 1; i <= 500; i++) {
System.out.println(i);
}
}
}
上面的代碼生成以下結(jié)果。
Java編程語(yǔ)言內(nèi)置了兩種線程同步:
在互斥同步中,在一個(gè)時(shí)間點(diǎn)只允許一個(gè)線程訪問(wèn)代碼段。
條件同步通過(guò)條件變量和三個(gè)操作來(lái)實(shí)現(xiàn):等待,信號(hào)和廣播。
synchronized關(guān)鍵字用于聲明需要同步的關(guān)鍵部分。
有兩種方法可以使用synchronized關(guān)鍵字:
我們可以通過(guò)在方法的返回類型之前使用關(guān)鍵字synchronized來(lái)聲明一個(gè)方法作為臨界段。
public class Main {
public synchronized void someMethod_1() {
// Method code goes here
}
public static synchronized void someMethod_2() {
// Method code goes here
}
}
我們可以聲明一個(gè)實(shí)例方法和一個(gè)靜態(tài)方法同步。構(gòu)造函數(shù)不能聲明為同步。
以下代碼說(shuō)明了使用關(guān)鍵字synchronized:
public class Main {
public synchronized void someMethod_1() {
// only one thread can execute here at a time
}
public void someMethod_11() {
synchronized (this) {
// only one thread can execute here at a time
}
}
public void someMethod_12() {
// multiple threads can execute here at a time
synchronized (this) {
// only one thread can execute here at a time
}
// multiple threads can execute here at a time
}
public static synchronized void someMethod_2() {
// only one thread can execute here at a time
}
public static void someMethod_21() {
synchronized (Main.class) {
// only one thread can execute here at a time
}
}
public static void someMethod_22() {
// multiple threads can execute here at a time
synchronized (Main.class) {
// only one thread can execute here at a time
}
// multiple threads can execute here at a time
}
}
對(duì)wait()方法的調(diào)用必須放在synchronized方法或同步塊中。
對(duì)于當(dāng)前線程已經(jīng)獲取監(jiān)視器的對(duì)象,必須調(diào)用wait()方法。
沒(méi)有辦法喚醒等待集中的特定線程。
public class Main {
private static int myValue = 1;
public static void main(String[] args) {
Thread t = new Thread(() -> {
while (true) {
updateBalance();
}
});
t.start();
t = new Thread(() -> {
while (true) {
monitorBalance();
}
});
t.start();
}
public static synchronized void updateBalance() {
System.out.println("start:" + myValue);
myValue = myValue + 1;
myValue = myValue - 1;
System.out.println("end:" + myValue);
}
public static synchronized void monitorBalance() {
int b = myValue;
if (b != 1) {
System.out.println("Balance changed: " + b);
System.exit(1);
}
}
}
上面的代碼生成以下結(jié)果。
以下代碼顯示了上述代碼的非同步版本。
public class Main {
private static int myValue = 1;
public static void main(String[] args) {
Thread t = new Thread(() -> {
while (true) {
updateBalance();
}
});
t.start();
t = new Thread(() -> {
while (true) {
monitorBalance();
}
});
t.start();
}
public static void updateBalance() {
System.out.println("start:" + myValue);
myValue = myValue + 1;
myValue = myValue - 1;
System.out.println("end:" + myValue);
}
public static synchronized void monitorBalance() {
int b = myValue;
if (b != 1) {
System.out.println("Balance changed: " + b);
System.exit(1);
}
}
}
上面的代碼生成以下結(jié)果。
更多建議: