Java multi-threaded locking object ReentrantLock and conditions of the object Condition

ReentrantLock display is called locked, synchronized is called implicit locks.

ReentrantLock Condition and only appeared in java 1.5, they are used to replace the traditional synchronized, wait (), notify () to enable collaboration between threads than using synchronized, use the Condition of await (), signal () which ways to achieve coordination between threads more secure and efficient.

ReentrantLock

ReentrantLock realized the Lock interface.

The basic structure of the protective ReentrantLock code block with the following:

myLock.lock();  // a ReentrantLock object
try
{
	critical section   //临界区代码
}
finally
{
	myLock.unlock(); // make sure the lock is unlocked even if an exception is thrown
}

This structure ensures that any time there is only one thread to enter the critical section. Once a thread is blocked lock object, not by any other thread lock statement. When another thread calls the lock, they are blocked until the first thread releases the lock object.

Condition

  • Condition is the interface, the basic approach is the await () and signal () method;
  • Lock Condition depends on the interface, generate a substantially Condition codes are lock.newCondition ()
  • Condition of calling await () and signal () method, must be within lock protection, that must only be used between lock.lock () and lock.unlock
  • Condition of the await () corresponding to the wait of Object ();
    Condition of the signal () corresponding to the Notify Object ();
    Condition in signalAll () corresponding to the notifyAll Object ().

ReentrantLock are synchronized and locked reentrant

Reentrant lock, also known as recursive lock, the same thread when the outer layer method to acquire the lock, and then enter the inner method will automatically acquire the lock, that is to say, any thread can enter a code block it already has a lock synchronized with the.
Look very good example to understand:
(1) Based on synchronized

public class ReentrantLockTest {
    public static void main(String[] args) {
        Phone phone = new Phone();
        // 第一个线程
        new Thread(() -> {
            phone.sendMsg();
        }, "t1").start();
        // 第二个线程
        new Thread(() -> {
            phone.sendMsg();
        }, "t2").start();
    }
}

class Phone {
    // 发送短信同步方法
    public synchronized void sendMsg() {
        System.out.println(Thread.currentThread().getName() + " called sendMsg()");
        // 进入另外一个同步着的方法
        sendEmail();
    }
    // 发送邮件同步方法
    public synchronized void sendEmail() {
        System.out.println(Thread.currentThread().getName() + " ******called sendEmail()");
    }
}

operation result:

t1 called sendMsg()             // t1线程在外层方法获取锁的时候
t1 ******called sendEmail()     // t1再进入内层方法会自动获取锁
t2 called sendMsg()
t2 ******called sendEmail()

(2) based ReentrantLock

public class ReentrantLockTest {
    public static void main(String[] args) {
        Phone phone = new Phone();
        // 第一个线程
        Thread t1 = new Thread(phone, "t1");
        // 第二个线程
        Thread t2 = new Thread(phone, "t2");

        t1.start();
        t2.start();
    }
}

class Phone implements Runnable {
    ReentrantLock lock = new ReentrantLock();
    // 发送短信方法
    public void sendMsg() {
        lock.lock();
        try {
            System.out.println(Thread.currentThread().getName() + " called sendMsg()");
            // 进入另一个方法
            sendEmail();
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            lock.unlock();
        }
    }
    // 发送邮件方法
    public void sendEmail() {
        lock.lock();
        try {
            System.out.println(Thread.currentThread().getName() + " ******called sendEmail()");
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            lock.unlock();
        }
    }

    @Override
    public void run() {
        sendMsg();
    }
}

operation result:

t1 called sendMsg()             // t1线程在外层方法获取锁的时候
t1 ******called sendEmail()     // t1再进入内层方法会自动获取锁
t2 called sendMsg()
t2 ******called sendEmail()
Published 516 original articles · won praise 89 · views 730 000 +

Guess you like

Origin blog.csdn.net/yzpbright/article/details/104644211
Recommended