1. Sum up
-
Multithreaded output loop output, is one of the concurrent programming interview frequently asked questions, to solve this kind of problem can be divided into two main solutions
-
Already plan
- Note: a thread a condition, do not mess
- Note:
condition
Approach is toAwait () and singal ()
notWait ()
-
The syn scheme
- When you multithread
NotifyAll ()
And andNotify ()
Be careful to distinguish
- When you multithread
-
A WHO variable is needed to calibrate whose turn it is to perform
-
Must first block, then output, then wake up, the order cannot change!!
- If you print first, then block and wake up last, you may get an error the first time you print (see below).
- in
reentrantLock
Next, the blocking judgment is usedif
orwhile
Can be - In syn, three-thread blocking can only be determined by using while(dual-thread blocking can be used)
if
)- This is due to
reentrantLock
You can let the specified thread wake up whilesyn
In the case of three threads onlynotifyAll
, and one of the threads needs to be blocked again
- This is due to
2. The two threads loop to print AB
Method of syn
public class AB_syn {
static int count = 0;
public static void main(String[] args) {
Object lock = new Object();
new Thread(() -> {
// Enter the lock before you can control it
synchronized (lock) {
// Print in an infinite loop
while (true) {
// If count is not equal to 0, then another thread needs to print and wait ().
while(count ! =0) {
try {
lock.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
System.out.println("A");
// Wake up thread 2
count = 1;
// While (count! =0) to block inside
lock.notify();
}
}
}).start();
new Thread(() -> {
// Put them in the lock before you can control them
synchronized (lock) {
// Print in an infinite loop
while (true) {
while(count ! =1) {
try {
lock.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
System.out.println("B");
count = 0; lock.notify(); } } }).start(); }}Copy the code
reentrantlock
import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.ReentrantLock;
public class AB_reentrylock {
static int who = 0;
public static void main(String[] args) {
ReentrantLock lock = new ReentrantLock();
Condition conditionA = lock.newCondition();
Condition conditionB = lock.newCondition();
new Thread(() -> {
try {
// Enter the lock first, then control
lock.lock();
while (true) {
while(who ! =0) {
conditionA.await();
}
System.out.println("A");
// Wake up B and queue B in AQS
conditionB.signal();
who = 1; }}catch (Exception e) {
e.printStackTrace();
} finally {
lock.unlock();
}
}).start();
new Thread(() -> {
try {
// Enter the lock first, then control
lock.lock();
while (true) {
while(who ! =1) {
conditionB.await();
}
System.out.println("B");
// Wake up A and queue up A in AQS
conditionA.signal();
who = 0; }}catch (Exception e) {
e.printStackTrace();
} finally{ lock.unlock(); } }).start(); }}Copy the code
3. Three threads print ABC
Method of syn
public class ABC_syn {
static int who = 0;
public static void main(String[] args) {
Object lock = new Object();
new Thread(() -> {
synchronized (lock) {
while (true) {
while(who ! =0) {
try {
lock.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
System.out.println("A");
who = 1;
lock.notifyAll();
}
}
}).start();
new Thread(() -> {
synchronized (lock) {
while (true) {
while(who ! =1) {
try {
lock.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
System.out.println("B");
who = 2;
lock.notifyAll();
}
}
}).start();
new Thread(() -> {
synchronized (lock) {
while (true) {
while(who ! =2) {
try {
lock.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
System.out.println("C");
who = 0; lock.notifyAll(); } } }).start(); }}Copy the code
reentrantlock
import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.ReentrantLock;
public class ABC_reentrylock {
static int count = 0;
public static void main(String[] args) {
ReentrantLock lock = new ReentrantLock();
lock.notifyAll();
Condition conditionA = lock.newCondition();
Condition conditionB = lock.newCondition();
Condition conditionC = lock.newCondition();
new Thread(() -> {
try {
// Lock and enter the concurrency control internal
lock.lock();
while (true) {
while(count ! =0) {
conditionA.await();
}
System.out.println("A");
// Enable the thread blocking conditionB to wake up
conditionB.signal();
count = 1; }}catch (Exception e) {
e.printStackTrace();
} finally {
lock.unlock();
}
}).start();
new Thread(() -> {
try {
// Lock and enter the concurrency control internal
lock.lock();
while (true) {
while(count ! =1) {
conditionB.await();
}
System.out.println("B");
// Enable the thread blocking conditionB to wake up
conditionC.signal();
count = 2; }}catch (Exception e) {
e.printStackTrace();
} finally {
lock.unlock();
}
}).start();
new Thread(() -> {
try {
// Lock and enter the concurrency control internal
lock.lock();
while (true) {
while(count ! =2) {
conditionC.await();
}
System.out.println("C");
// Enable the thread blocking conditionB to wake up
conditionA.signal();
count = 0; }}catch (Exception e) {
e.printStackTrace();
} finally{ lock.unlock(); } }).start(); }}Copy the code
4. Why do you need to judge blocking before printing?
In this case, if thread 2 starts the execution first, it will cause the first output to be B first. In the case of three threads, there is no guarantee that the first output will be A
public class AB_syn2 {
static int count = 0;
public static void main(String[] args) {
Object lock = new Object();
new Thread(() -> {
// Put them in the lock before you can control them
synchronized (lock) {
// Print in an infinite loop
while (true) {
System.out.println("A");
// Wake up thread 2
count = 1;
lock.notify();
try {
lock.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}).start();
new Thread(() -> {
// Put them in the lock before you can control them
synchronized (lock) {
// Print in an infinite loop
while (true) {
System.out.println("B");
count = 0;
lock.notify();
try {
lock.wait();
} catch(InterruptedException e) { e.printStackTrace(); } } } }).start(); }}Copy the code
5. Write a deadlock
- The four elements of a deadlock:
- Exclusive access
- Ask and hold
- Do not deprive
- Loop waiting for
- In simple terms, two locks (AB), with one thread holding A and the other thread holding B, request each other’s resources
public classA deadlock{
public static void main(String[] args) {
Object A = new Object();
Object B = new Object();
new Thread(() -> {
synchronized (A) {
System.out.println("Got an A");
try {
Thread.sleep(100);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("Try to get B after 100 milliseconds.");
synchronized (B){
System.out.println("bbbb");
}
}
}).start();
new Thread(() -> {
synchronized (B) {
System.out.println("Got a B");
try {
Thread.sleep(100);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("Try to get A after 100 milliseconds.");
synchronized (A){
System.out.println("aaaa"); } } }).start(); }}Copy the code