May 10, 2021 Java
The following code shows how to run multithreaded in a program.
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);
}
}
}
The code above produces the following results.
The Java programming language has two thread synchronizations built in:
In mutually exclusive synchronization, only one thread is allowed to access the snippt at one point in time.
Conditional synchronization is achieved by condition variables and three operations: wait, signal, and broadcast.
The synchronized keyword is used to declare the key parts that need to be synchronized.
There are two ways to use the synchronized keyword:
We can declare a method as a critical segment by using the keyword synchronized before the method's return type.
public class Main {
public synchronized void someMethod_1() {
// Method code goes here
}
public static synchronized void someMethod_2() {
// Method code goes here
}
}
We can declare an instance method to synchronize with a static method. The constructor cannot be declared as synchronous.
The following code explains the use of the keyword 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
}
}
Calls to the wait() method must be placed in the syncronized method or synchronization block.
The wait() method must be called for objects that the current thread has acquired the monitor.
There is no way to wake a specific thread waiting for a set.
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);
}
}
}
The code above produces the following results.
The following code shows the non-synchronized version of the above code.
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);
}
}
}
The code above produces the following results.