Multithreaded Printing ABC Problem

AB thread printing 1 to 10 alternately synchronized+notifyAll+wait: indirect access by AB threads using num++. public cl...
First
Second
First
Second
Third
Fourth

AB thread printing 1 to 10 alternately

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:10
AB 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 alternately

First

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 Problem

First

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)

1 October 2021, 13:11 | Views: 1523

Add new comment

For adding a comment, please log in
or create account

0 comments