Java multi-threading learning (five) - wait for notification mechanism

Wait for notification mechanism of realization

Method of action wait () is to the current thread to wait, wait () method is a method Object class, for which the current thread into the "pre-execution queue" and wait () stops executing the code at the location, until notified or interrupt occurs. After only synchronization method used in fast synchronization or wait () method, executed wait (), the current thread releases the lock.

Object method notify () method or synchronous also call in sync fast, before calling must also obtain the object level locks. The method used to notify other threads that may be waiting for this object's lock, if there are multiple threads waiting thread by thread planner randomly selected a wait state, it issued a notice notify, so he waiting to acquire the object lock .

After performing the notify () the current thread does not immediately release the lock, exit synchronized block of code will release the lock in the thread, the thread in a wait state before they can acquire the lock. When the first acquire the object lock wait thread releases the lock end of the run, if the object does not notify again, other threads wait state will still blocked wait until this object emits notify or notifyAll.

public class MyWait {

    private final Object lock;

    MyWait(Object lock){
        this.lock=lock;
    }

    public void waitTest(){
        try {
            synchronized (lock){
                System.out.println("开始 wait time = " + System.currentTimeMillis());
                lock.wait();
                System.out.println("结束 wait time = " + System.currentTimeMillis());
            }
        }catch (InterruptedException e){
            e.printStackTrace();
        }
    }
}
复制代码
public class MyNotify {
    private final Object lock;

    MyNotify(Object lock){
        this.lock=lock;
    }

    public void notifyTest(){
        synchronized (lock){
            System.out.println("开始 notify time = " + System.currentTimeMillis());
            lock.notify();
            System.out.println("结束 notify time = " + System.currentTimeMillis());
        }
    }

}
复制代码
public class Main {

    public static void main(String[] args){
        try {
            Object lock = new Object();
            MyWait myWait = new MyWait(lock);
            new Thread(() -> myWait.waitTest()).start();
            Thread.sleep(3000);
            MyNotify myNotify = new MyNotify(lock);
            new Thread(() -> myNotify.notifyTest()).start();
        }catch (InterruptedException e){
            e.printStackTrace();
        }
    }
}
复制代码
开始 wait time = 1552812964325
开始 notify time = 1552812967328
结束 notify time = 1552812967328
结束 wait time = 1552812967328
复制代码

As can be seen from the content output the notify method performed for 3 seconds, and the method is performed after the end of execution wait notify method.

Related Methods

  • wait (): the thread calls this method to release a shared resource lock, then withdraw from the run state and enters the waiting queue, until they were awakened again.
  • wait (long): Timeout waiting for some time, here is the parameter of time in milliseconds, that is, to wait up to n milliseconds if no notice timeouts return.
  • notify (): random wakeup waiting in the queue waiting for the same shared resource "a thread", the thread exits and waiting queue, runnable, that is, notify () method notifies only "a thread."
  • notifyAll (): all "All threads" are waiting in the queue waiting to exit the same shared resource wait queue runnable. At this time, the highest priority thread that executed first, but it could also be performed randomly, depending on the implementation JVM virtual machine.

The basic state of the thread

Reprinted with https://blog.csdn.net/qq_34337272/article/details/79690279

  1. New (new new) : create a new thread object.

  2. Run (Runnable) : After the thread object is created, other threads (such as main thread) calls the start () method of the object. The thread state is located runnable threads in the pool, waiting to be selected thread scheduling, acquiring the right to use the cpu.

  3. Operating (running) : runnable (Runnable) obtained threads of cpu time slice (timeslice), execution of program code.

  4. Blocking (Block) : blocking state is the thread for some reason to give up the right to use the cpu, that is let out of the cpu timeslice, temporarily stop running. Until the thread becomes runnable (runnable) state, you have a chance to get cpu timeslice to run (running) state again. Case of obstruction of three categories:

(A). Wait blocking : a thread of execution o.wait running (running) () method, JVM will thread into the wait queue (waitting queue) in.

(B) synchronous blocking : thread running (running) when acquiring synchronization lock object, if the synchronization lock is occupied by another thread, the JVM will lock into the thread pool (lock pool) in.

(三). **其他阻塞**: 运行(running)的线程执行Thread.sleep(long ms)或t.join()方法,或者发出了I/O请求时,JVM会把该线程置为阻塞状态。当sleep()状态超时join()等待线程终止或者超时、或者I/O处理完毕时,线程重新转入可运行(runnable)状态。
复制代码
  1. Death (Dead) : Thread run (), main () method has finished executing, or due to abnormal withdrew from the run () method, the thread end of the life cycle. Thread of death can not be resurrected again.

This section of code GitHub

Use join the

In many cases, the main thread to create and promoter thread, if the operator takes a lot of thread, the main thread is often the end of the encounter before the end of the child thread. If, after the main thread to wait for the child thread execution is complete at the end, we must use the join () method, join () function is waiting thread object is destroyed.

Thread class addition to join () method, but also provides a join (long millis), join (long millis, int nanos) having two timeouts characteristics. These two methods timeout said that if the thread thread does not terminate in the specified timeout period, it will be returned from the timeout method.

public class Main {

    public static void main(String[] args) throws InterruptedException{
        Thread thread = new Thread(() -> {
            try {
                System.out.println(Thread.currentThread().getName()+"正在执行");
                Thread.sleep(1000);
            }catch (InterruptedException e){
                e.printStackTrace();
            }
        }, "线程1");
        thread.start();
        thread.join();
        System.out.println("等待"+thread.getName()+"执行完");
    }
}
// 输出
线程1正在执行
等待线程1执行完
复制代码

Difference jain (long) and sleep (long) of

The method join (long) function is used wait (long) method implemented in the interior, so join (long) method releases the lock features. Two sleep (long) does not release the lock.

Use of ThreadLocal

Variable values ​​can be used in the form of shared public static variables, all the threads use the same public static variable, if you want to achieve each thread has its own share ThreadLocal variables can be used to solve.

ThreadLocal related methods:

  • () Get: Returns the value of the current thread's copy of this thread-local variable in.
  • set (T value): a copy of the current thread of this thread-local variable to the specified value.
  • () Remove: delete this thread-local value of the current thread.
  • initialValue (): "initial value" to return to this thread-local variable for the current thread.

Isolation of variables between threads

public class ThreadLocalTeat {
    public static ThreadLocal<String> threadLocal = new ThreadLocal<>();

    public static void main(String[] args) throws InterruptedException{
        int count = 30;
        String name = "Thread-";
        for (int i=0; i<count; i++){
            Thread thread = new Thread(() -> {
                threadLocal.set(Thread.currentThread().getName());
                System.out.println(threadLocal.get());
            }, name+i);
            thread.start();
        }
        Thread.sleep(20000);
    }
}
// 输出
Thread-0
Thread-4
Thread-3
Thread-6
Thread-2
Thread-1
Thread-7
。。。
复制代码

The use InheritableThreadLocal

Use class InheritableThreadLocal can get the parent thread inherited values ​​in the child thread.

public class InheritableThreadLocalTest extends InheritableThreadLocal {
    @Override
    protected Object childValue(Object parentValue) {
        return super.childValue(parentValue);
    }

    @Override
    protected Object initialValue() {
        return System.currentTimeMillis();
    }
}
复制代码
 * @date 2019/6/18 8:28
 * @description
 */
public class InheritableTeat {
    static public class Inner{
        public static InheritableThreadLocalTest threadLocalTest = new InheritableThreadLocalTest();
    }


    public static void main(String[] args) throws InterruptedException{
        for (int i = 0; i<3; i++){
            System.out.println("在main线程中获取值:"+ Inner.threadLocalTest.get());
        }

                for (int i=0; i<3; i++){
                    new Thread(() -> {
                        System.out.println("在"+Thread.currentThread().getName()+"中获取值:"+ Inner.threadLocalTest.get());
            }, "Thread-"+i).start();
        }
        Thread.sleep(1000);

    }

}
// 输出
在main线程中获取值:1560818029616
在main线程中获取值:1560818029616
在main线程中获取值:1560818029616
在Thread-1中获取值:1560818029616
在Thread-2中获取值:1560818029616
在Thread-0中获取值:1560818029616
复制代码

In use InheritableThreadLocal class thing to note: if the child thread in obtaining the value of the main thread in the value InheritableThreadLocal make changes, then the child thread was taken to the old values.


Welcome to public concern number:

No micro-channel public

Guess you like

Origin juejin.im/post/5d783fa1e51d4561ae4da6ab