以下代碼顯示了如何在程序中運行多線程。
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編程語言內(nèi)置了兩種線程同步:
在互斥同步中,在一個時間點只允許一個線程訪問代碼段。
條件同步通過條件變量和三個操作來實現(xiàn):等待,信號和廣播。
synchronized關(guān)鍵字用于聲明需要同步的關(guān)鍵部分。
有兩種方法可以使用synchronized關(guān)鍵字:
我們可以通過在方法的返回類型之前使用關(guān)鍵字synchronized來聲明一個方法作為臨界段。
public class Main {
public synchronized void someMethod_1() {
// Method code goes here
}
public static synchronized void someMethod_2() {
// Method code goes here
}
}
我們可以聲明一個實例方法和一個靜態(tài)方法同步。構(gòu)造函數(shù)不能聲明為同步。
以下代碼說明了使用關(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
}
}
對wait()方法的調(diào)用必須放在synchronized方法或同步塊中。
對于當前線程已經(jīng)獲取監(jiān)視器的對象,必須調(diào)用wait()方法。
沒有辦法喚醒等待集中的特定線程。
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é)果。
更多建議: