Lock lock and Condition condition

Talking about Synchronized:

  Synchronized is a keyword in Java, which is a built-in feature of the Java language. If a code block is modified by synchronized, when a thread acquires the corresponding lock and executes the code block, other threads

You can only wait until the thread that acquires the lock releases the lock, and the thread that acquires the lock releases the lock in three cases:

  1). The thread that acquires the lock finishes executing the code block, and then the thread releases the possession of the lock;

  2). When an exception occurs in the execution of the thread, the JVM will let the thread automatically release the lock;

  3). Call the wait method to release the lock immediately while waiting, so that other threads can use the lock.

 

Features of Lock:

  1).Lock is not built-in in the Java language;

  2). Synchronized is implemented at the JVM level. If there is an exception in the code execution, the JVM will automatically release the lock , but Lock does not work. To ensure that the lock will be released, you must put unLock in finally{} ( manual release ) ;

  3). In the case where resource competition is not very fierce, the performance of Synchronized is better than that of ReetarntLock, but in very intense cases, the performance of synchronized will drop dozens of times;

  4).ReentrantLock adds locks:

    a. void lock(); // unconditional lock;

    b. void lockInterruptibly throws InterruptedException;//Interrupt lock;

Explanation: Use ReentrantLock to return immediately if the lock is acquired. If the lock is not acquired, the current thread is in a sleep state until the lock is acquired or the current thread can be interrupted by other threads to do other things; but if it is synchronized, if it is not acquired lock, it will wait forever;

    c. boolean tryLock();//If the lock is acquired, return true immediately, if another thread is holding it, return false immediately, and will not wait;

    d. boolean tryLock(long timeout, TimeUnit unit);//If the lock is acquired, return true immediately. If another thread is holding the lock, it will wait for the time given by the parameter. During the waiting process, if the lock is acquired, it will return true, if the wait times out, return false;

 

Features of Condition:

    1. The await() method in Condition is equivalent to the wait() method of Object, the signal() method in Condition is equivalent to the notify() method of Object, and the signalAll() method in Condition is equivalent to the notifyAll() method of Object. The difference is that these methods in Object are bundled with synchronization locks; Condition needs to be bundled with mutex/shared locks.

    2.Condition is more powerful in that it can control the sleep and wake-up of multiple threads more finely. For the same lock, we can create multiple conditions and use different conditions in different situations.
    For example, if multiple threads read/write the same buffer: after writing data to the buffer, wake up the "reading thread"; after reading data from the buffer, wake up the "writing thread"; and when the buffer is full When the "write thread" needs to wait; when the buffer is empty, the "read thread" needs to wait.      

      If you use wait(), notify(), notifyAll() in the Object class to implement the buffer, when you need to wake up the "reading thread" after writing data to the buffer, it is impossible to explicitly use notify() or notifyAll() Specify to wake up the "read thread", and only wake up all threads through notifyAll (but notifyAll cannot distinguish whether the awakened thread is a read thread or a write thread). However, through Condition, the read thread can be explicitly specified to wake up.

 

synchronized{

wait();

notify();

}

==

lock{

condition.wait()'

condition.single();

 

}

unlock()

 

 

 

 

 

copy code
package com.imooc.locks;

import java.util.LinkedList;
import java.util.List;
import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;

public class Task {
    
    private final Lock lock = new ReentrantLock();
    
    private final Condition addCondition = lock.newCondition();
    
    private final Condition subCondition = lock.newCondition();
    
    
    private static int num = 0;
    private List<String> lists = new LinkedList<String>();
    
    public void add() {
        lock.lock();
        
        try {
             while (lists.size() == 10) { // When the collection is full, the "add" thread waits for 
                addCondition.await();
            }
            
            num ++ ;
            lists.add("add Banana" + num);
            System.out.println("The Lists Size is " + lists.size());
            System.out.println("The Current Thread is " + Thread.currentThread().getName());
            System.out.println("==============================");
            this.subCondition.signal();
            
        } catch (InterruptedException e) {
            e.printStackTrace ();
        } finally { // release the lock 
            lock.unlock();
        }
    }
    
    
    public  void sub () {
        lock.lock();
        
        try {
             while (lists.size() == 0) { // When the collection is empty, the "reduce" thread waits for 
                subCondition.await();
            }
            
            String str = lists.get(0);
            lists.remove(0);
            System.out.println("The Token Banana is [" + str + "]");
            System.out.println("The Current Thread is " + Thread.currentThread().getName());
            System.out.println("==============================");
            num -- ;
            addCondition.signal();
            
        } catch (InterruptedException e) {
            e.printStackTrace ();
        } finally {
            lock.unlock();
        }
    }
    
}
copy code
copy code
package com.imooc.locks;

public class AddThread implements Runnable {
    
    private Task task;
    
    public AddThread(Task task) {
        this.task = task;
    }

    @Override
    public void run() {
        task.add();
    }

}
copy code
copy code
package com.imooc.locks;

public class SubThread implements Runnable {
    
    private Task task;
    
    public SubThread(Task task) {
        this.task = task;
    }

    @Override
    public void run() {
        task.sub();
    }

}
copy code
copy code
package com.imooc.locks;

public class TestLock {
    
    public static void main(String[] args) {
        Task task = new Task();
        
        Thread t1=new Thread(new AddThread(task));
        Thread t3=new Thread(new AddThread(task));
        Thread t7=new Thread(new AddThread(task));
        Thread t8=new Thread(new AddThread(task));
        Thread t2 = new Thread(new SubThread(task));
        Thread t4 = new Thread(new SubThread(task));
        Thread t5 = new Thread(new SubThread(task));
        Thread t6 = new Thread(new SubThread(task));
        
        t1.start();
        t2.start();
        t3.start();
        t4.start();
        t5.start();
        t6.start();
        t7.start();
        t8.start();
    }

}

Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=326012897&siteId=291194637