1. Introduction
This summary summarizes my understanding of the communication methods between threads in JAVA multi-threading. I mainly discuss the communication between threads using code combined with text, so I excerpted some of the passages from the book. Sample code.
2. Communication methods between threads
①Synchronization
The synchronization mentioned here refers to the communication between multiple threads through the synchronized keyword.
Reference example:
public class MyObject { synchronized public void methodA() { //do something.... } synchronized public void methodB() { //do some other thing } } public class ThreadA extends Thread { private MyObject object; //省略构造方法 @Override public void run() { super.run(); object.methodA(); } } public class ThreadB extends Thread { private MyObject object; //省略构造方法 @Override public void run() { super.run(); object.methodB(); } } public class Run { public static void main(String[] args) { MyObject object = new MyObject(); //线程A与线程B 持有的是同一个对象:object ThreadA a = new ThreadA(object); ThreadB b = new ThreadB(object); a.start(); b.start(); } }
Since thread A and thread B hold the same object object of the MyObject class, although the two threads need to call different methods, they are executed synchronously. For example: Thread B needs to wait for thread A to finish executing the methodA() method before it can execute the methodB() method. In this way, thread A and thread B achieve communication.
This method is essentially "shared memory" communication. Multiple threads need to access the same shared variable. Whoever gets the lock (obtains access permission) can execute it.
②while polling method
The code is as follows:
import java.util.ArrayList; import java.util.List; public class MyList { private List<String> list = new ArrayList<String>(); public void add() { list.add("elements"); } public int size() { return list.size(); } } import mylist.MyList; public class ThreadA extends Thread { private MyList list; public ThreadA(MyList list) { super(); this.list = list; } @Override public void run() { try { for (int i = 0; i < 10; i++) { list.add(); System.out.println("添加了" + (i + 1) + "个元素"); Thread.sleep(1000); } } catch (InterruptedException e) { e.printStackTrace(); } } } import mylist.MyList; public class ThreadB extends Thread { private MyList list; public ThreadB(MyList list) { super(); this.list = list; } @Override public void run() { try { while (true) { if (list.size() == 5) { System.out.println("==5, 线程b准备退出了"); throw new InterruptedException(); } } } catch (InterruptedException e) { e.printStackTrace(); } } } import mylist.MyList; import extthread.ThreadA; import extthread.ThreadB; public class Test { public static void main(String[] args) { MyList service = new MyList(); ThreadA a = new ThreadA(service); a.setName("A"); a.start(); ThreadB b = new ThreadB(service); b.setName("B"); b.start(); } }
In this way, thread A constantly changes the conditions, and thread ThreadB constantly detects this through the while statement Whether the condition (list.size()==5) is established, thereby realizing communication between threads. But this method will waste CPU resources. The reason why it is said to be a waste of resources is because when the JVM scheduler hands the CPU to thread B for execution, it does not do any "useful" work. It is just constantly testing whether a certain condition is true. It's similar to how in real life, a person keeps looking at the phone screen to see if a call is coming, instead of: doing other things. When a call comes, the phone rings to notify him/her that the call is coming.
③wait/notify mechanism
The code is as follows:
import java.util.ArrayList; import java.util.List; public class MyList { private static List<String> list = new ArrayList<String>(); public static void add() { list.add("anyString"); } public static int size() { return list.size(); } } public class ThreadA extends Thread { private Object lock; public ThreadA(Object lock) { super(); this.lock = lock; } @Override public void run() { try { synchronized (lock) { if (MyList.size() != 5) { System.out.println("wait begin " + System.currentTimeMillis()); lock.wait(); System.out.println("wait end " + System.currentTimeMillis()); } } } catch (InterruptedException e) { e.printStackTrace(); } } } public class ThreadB extends Thread { private Object lock; public ThreadB(Object lock) { super(); this.lock = lock; } @Override public void run() { try { synchronized (lock) { for (int i = 0; i < 10; i++) { MyList.add(); if (MyList.size() == 5) { lock.notify(); System.out.println("已经发出了通知"); } System.out.println("添加了" + (i + 1) + "个元素!"); Thread.sleep(1000); } } } catch (InterruptedException e) { e.printStackTrace(); } } } public class Run { public static void main(String[] args) { try { Object lock = new Object(); ThreadA a = new ThreadA(lock); a.start(); Thread.sleep(50); ThreadB b = new ThreadB(lock); b.start(); } catch (InterruptedException e) { e.printStackTrace(); } } }
Thread A needs to wait until a certain condition is met (list.size()==5) before executing the operation. Thread B adds elements to the list and changes the size of the list.
How do A and B communicate? In other words, how does thread A know that list.size() is already 5?
The wait() and notify() methods of the Object class are used here.
When the conditions are not met (list.size() !=5), thread A calls wait() to give up the CPU and enter the blocking state. ---It does not occupy the CPU like ②while polling
When the conditions are met, thread B calls notify() to notify thread A. The so-called notification of thread A is to wake up thread A and let it enter the runnable state.
One benefit of this method is that the CPU utilization rate is improved.
But there are also some shortcomings: for example, thread B executes first, adds 5 elements at once and calls notify() to send a notification, while thread A is still executing at this time; when thread A executes and calls wait (), then it can never be awakened. Because thread B has already sent a notification and will no longer send notifications in the future. This shows that notifying too early will disrupt the execution logic of the program.
The above article provides an in-depth understanding of the communication methods between threads in JAVA multi-threading. This is all the content shared by the editor. I hope it can give you a reference, and I also hope that everyone will support the PHP Chinese website.
For more in-depth understanding of the communication methods between JAVA multi-threads, please pay attention to the PHP Chinese website!