synchronized+notifyAll+wait: indirect access by AB threads using num++.
public class thread1_100 { public static int num=1; private static final Object lock=new Object(); private void print(int target){ if(num>10) { return ; } synchronized (lock){ while(num<=10){ System.out.print(Thread.currentThread().getName()+": "); System.out.print(num); num++; lock.notifyAll(); try { lock.wait(); } catch (InterruptedException e) { e.printStackTrace(); } } lock.notifyAll();//Main Thread } } public static void main(String[] args) { thread1_100 thread1_100=new thread1_100(); new Thread(()->,"A").start(); new Thread(()->,"B").start(); } }
The results show that:
A:1B:2A:3B:4A:5B:6A:7B:8A:9B:10AB thread printing 1 to 10 (2) alternately
synchronized+notifyAll+wait: alternate printing using odd and even numbers
public class thread2__1_100 { public static void main(String[] args) { thread2__1_100 thread2__1_100=new thread2__1_100(); new Thread(()->,"A").start(); new Thread(()->,"B").start(); } private static int num=0; private static final Object lock=new Object(); private void printabc(int targetname) { while (true) { synchronized (lock) { while (num % 2 != targetname) { if(num>=10){//The main thread did not exit break; } try { lock.wait(); } catch (InterruptedException e) { e.printStackTrace(); } } if (num >=10) { break; } num++; System.out.print(Thread.currentThread().getName() + ":" + num); lock.notifyAll(); } } } }
A:1B:2A:3B:4A:5B:6A:7B:8A:9B:10
The wait() method and notifyAll() method locations of the first two methods require more thought
Multiple threads printing 1-n alternatelyFirst
From the first two examples, it can be judged that the thought on this topic can be deduced
If we use the first method to add at most one c at the end, we run a few more times and find problems
public class thread1_100 { public static int num=1; private static final Object lock=new Object(); private void print(int target){ if(num>10) { return ; } synchronized (lock){ while(num<=10){ System.out.print(Thread.currentThread().getName()+":"); System.out.print(num); num++; lock.notifyAll(); try { lock.wait(); } catch (InterruptedException e) { e.printStackTrace(); } } lock.notifyAll();//Main Thread } } public static void main(String[] args) { thread1_100 thread1_100=new thread1_100(); new Thread(()->,"A").start(); new Thread(()->,"B").start(); new Thread(()->,"c").start(); } }
Result:
A:1B:2A:3B:4A:5B:6A:7c:8A:9B:10 A:1B:2A:3B:4A:5B:6A:7c:8B:9c:10
After the lock.notifyAll() method is executed, it is not guaranteed that the order will be ABC, so different results will occur.
Second
Judged by% based on the second method above
public class thread2__1_100 { public static void main(String[] args) { thread2__1_100 thread2__1_100=new thread2__1_100(); new Thread(()->,"A").start(); new Thread(()->,"B").start(); new Thread(()->,"C").start(); } private static int num=0; private static final Object lock=new Object(); private void printabc(int targetname) { while (true) { synchronized (lock) { while (num % 3 != targetname) { if(num>=10){//The main thread did not exit break; } try { lock.wait(); } catch (InterruptedException e) { e.printStackTrace(); } } if (num >=10) { break; } num++; System.out.print(Thread.currentThread().getName() + ":" + num); lock.notifyAll(); } } } }
Result:
A:1B:2C:3A:4B:5C:6A:7B:8C:9A:10
You'll find that as expected, the same rule applies when the number of homogeneous threads increases.
Alternate Printing ABC ProblemFirst
Use Lock's corresponding usage method
public class thread4_1_100 { private int num=0; private Lock lock=new ReentrantLock(); private void printabc(String name,int targetnum){ for (int i = 0; i <10;) { lock.lock();//Locking if(num%3==targetnum){ num++; i++;//Make sure I'm looking for me to let i++. System.out.print(name); } lock.unlock();//Unlock after operation } } public static void main(String[] args) { thread4_1_100 thread4_1_100=new thread4_1_100(); new Thread(()->).start(); new Thread(()->).start(); new Thread(()->).start(); } }
Result:
ABCABCABCABCABCABCABCABCABCABC
Second
Using the join() method:
join(): Like the sleep() method, it is an interruptable method that calls the join() method of another thread in one thread, causing the current thread to hang until the end of the thread executing the join() method. (!!) For example, calling the join() method of the A thread in the B thread, the B thread enters a blocking state until the A thread ends or reaches the specified time.
Since it is a two-threaded operation, there will be forward and backward threaded operations
public class thread3_1_100 { public static void main(String[] args) throws InterruptedException { for (int i = 0; i <10 ; i++) { Thread t1 = new Thread(new printabc(null), "A"); Thread t2 = new Thread(new printabc(t1), "B"); Thread t3 = new Thread(new printabc(t2), "C"); t1.start(); t2.start(); t3.start(); Thread.sleep(10);//Necessary } } } class printabc implements Runnable{ public printabc(Thread beforeThread) { this.beforeThread = beforeThread; } private Thread beforeThread; @Override public void run() { if(beforeThread!=null){//The first thread is an exception try { beforeThread.join();//The previous thread called join() System.out.print(Thread.currentThread().getName()); } catch (InterruptedException e) { e.printStackTrace(); } }else{ System.out.print(Thread.currentThread().getName()+""); } } }
Result:
ABCABCABCABCABCABCABCABCABCABC
Third
Precise wake-up using lock+Condition
Which one needs waking up is A wake up B,B wake up C,C wake up A loop in turn
Next thread.signal();Method
//Precise wake-up public class thread5_1_100 { private int num; private static Lock lock=new ReentrantLock(); private static Condition c1=lock.newCondition(); private static Condition c2=lock.newCondition(); private static Condition c3=lock.newCondition(); private void printabc(String name, int targetnum, Condition curthread,Condition nextthread){ for(int i=0;i<10;){ lock.lock(); while(num%3!=targetnum){ try { curthread.await(); } catch (InterruptedException e) { e.printStackTrace(); } } num++; i++; System.out.print(name); nextthread.signal(); lock.unlock(); } } public static void main(String[] args) { thread5_1_100 thread5_1_100=new thread5_1_100(); new Thread(()->).start(); new Thread(()->).start(); new Thread(()->).start(); }
Result:
ABCABCABCABCABCABCABCABCABCABC
Fourth
Use Signal Quantity
public class thread6_1_100 { public Semaphore c1 = new Semaphore(1); public Semaphore c2 = new Semaphore(0); public Semaphore c3 = new Semaphore(0); public static void main(String[] args) { new thread6_1_100().printABC(); } public void printABC() { ExecutorService exe = Executors.newCachedThreadPool(); Thread t1 = new Thread() { @Override public void run() { while (true) { try { c1.acquire(); System.out.print("A"); c2.release(); } catch (InterruptedException e) { e.printStackTrace(); } } } }; Thread t2 = new Thread() { @Override public void run() { while (true) { try { c2.acquire(); System.out.print("B"); c3.release(); } catch (InterruptedException e) { e.printStackTrace(); } } } }; Thread t3 = new Thread() { @Override public void run() { while (true) { try { c3.acquire(); System.out.print("C"); c1.release(); } catch (InterruptedException e) { e.printStackTrace(); } } } }; exe.execute(t1); exe.execute(t2); exe.execute(t3); } }
Second blog from Senior (Xiao Bai)