Details of important methods in Thread and Object classes
Overview of methods
wait,notify,notifyAll
Function and usage: blocking phase, wake-up phase, interrupt encountered
- It will not wake up until one of the following four conditions occurs
- Another thread calls the notify() method of this object and it is the thread that is just woken up
- Another thread calls the notifyAll() method of this object
- After the timeout specified by wait(long timeout), if 0 is passed in, it is a permanent wait;
- Thread itself called interrupt()
Code demonstration: show the basic usage of wait and notify
- Study code execution order
- Prove wait release lock
public class Wait { public static Object object = new Object(); static class Thread1 extends Thread { @Override public void run() { synchronized (object) { System.out.println(Thread.currentThread().getName() + "It's on"); try { object.wait(); } catch (InterruptedException e) { e.printStackTrace(); } System.out.println("thread" + Thread.currentThread().getName() + "Lock acquired."); } } } static class Thread2 extends Thread { @Override public void run() { synchronized (object) { object.notify(); System.out.println("thread" + Thread.currentThread().getName() + "Called notify()"); } } } public static void main(String[] args) throws InterruptedException { Thread1 thread1 = new Thread1(); Thread2 thread2 = new Thread2(); thread1.start(); Thread.sleep(200); thread2.start(); } }
Code demonstration: three threads, thread 1 and thread 2 are blocked first, and thread 3 wakes them up. notify, notifyAll and start do not mean that the thread starts first.
public class WaitNotifyAll implements Runnable { private static final Object resourceA = new Object(); public static void main(String[] args) throws InterruptedException { Runnable r = new WaitNotifyAll(); Thread threadA = new Thread(r); Thread threadB = new Thread(r); Thread threadC = new Thread(() -> { synchronized (resourceA) { // resourceA.notifyAll(); resourceA.notify(); System.out.println("ThreadC notified."); } }); threadA.start(); threadB.start(); Thread.sleep(200); threadC.start(); } @Override public void run() { synchronized (resourceA) { System.out.println(Thread.currentThread().getName()+" got resourceA lock."); try { System.out.println(Thread.currentThread().getName()+" waits to start."); resourceA.wait(); System.out.println(Thread.currentThread().getName()+"'s waiting to end."); } catch (InterruptedException e) { e.printStackTrace(); } } } }
Code demonstration: prove that wait only releases the current lock
public class WaitNotifyReleaseOwnMonitor { private static volatile Object resourceA = new Object(); private static volatile Object resourceB = new Object(); public static void main(String[] args) { Thread thread1 = new Thread(() -> { synchronized (resourceA) { System.out.println("ThreadA got resourceA lock."); synchronized (resourceB) { System.out.println("ThreadA got resourceB lock."); try { System.out.println("ThreadA releases resourceA lock."); resourceA.wait(); } catch (InterruptedException e) { e.printStackTrace(); } } } }); Thread thread2 = new Thread(() -> { try { Thread.sleep(1000); } catch (InterruptedException e) { e.printStackTrace(); } synchronized (resourceA) { System.out.println("ThreadB got resourceA lock."); System.out.println("ThreadB tries to resourceB lock."); synchronized (resourceB) { System.out.println("ThreadB got resourceB lock."); } } }); thread1.start(); thread2.start(); } }
principle
- Must have monitor lock
- notify can only wake up one
- Belongs to Object class
- Condition s of similar functions
- Holding multiple locks at the same time
sleep
- Function: only want the thread to execute at the expected time, and do not use CPU resources at other times
- Do not release locks, including synchronized and lock locks, which are different from wait
Code demonstration: when displaying thread sleep, do not release the synchronized monitor. When the sleep time is up, release the lock after the normal end
public class SleepDontReleaseMonitor implements Runnable { public static void main(String[] args) { SleepDontReleaseMonitor sleepDontReleaseMonitor = new SleepDontReleaseMonitor(); new Thread(sleepDontReleaseMonitor).start(); new Thread(sleepDontReleaseMonitor).start(); } @Override public void run() { syn(); } private synchronized void syn() { System.out.println("thread" + Thread.currentThread().getName() + "Got it. monitor. "); try { Thread.sleep(5000); } catch (InterruptedException e) { e.printStackTrace(); } System.out.println("thread" + Thread.currentThread().getName() + "Out of sync block"); } }
Features of sleep method: sleep method can let the thread enter the Waiting state, and does not occupy CPU resources, but does not release the lock until the specified time before execution. If it is interrupted during sleep, an exception will be thrown and the interrupt state will be cleared.
More elegant implementation of sleep: TimeUnit.SECONDS.sleep()
join
Function: because the new thread has joined us, we will not start until it finishes executing
Usage: the child thread waiting to be joined by the main thread, pay attention to who waits for whom
Encapsulated tool class: CountDownLatch or CyclicBarrier class
What state is the main thread in during join: WAITING state
Code demonstration: demonstrate the join, pay attention to the statement output order, it will change.
public class Join { public static void main(String[] args) throws InterruptedException { Thread thread = new Thread(() -> { try { Thread.sleep(1000); } catch (InterruptedException e) { e.printStackTrace(); } System.out.println(Thread.currentThread().getName() + "completion of enforcement"); }); Thread thread2 = new Thread(() -> { try { Thread.sleep(1000); } catch (InterruptedException e) { e.printStackTrace(); } System.out.println(Thread.currentThread().getName() + "completion of enforcement"); }); thread.start(); thread2.start(); System.out.println("Start waiting for child threads to finish running"); thread.join(); thread2.join(); System.out.println("All child threads completed"); } }
yield
Function: release my CPU time slice
Positioning: JVM does not guarantee compliance
Difference between yield and sleep: whether it is possible to be scheduled again at any time
Thread.currentThread()
Function: the current thread can print the thread name, ID, etc. of the current thread
start,run
The previous article has introduced!
stop,suspend,resume
These methods have been abandoned!