Small knowledge, big challenge! This article is participating in the creation activity of “Essential Tips for Programmers”.
Java multithreaded read and write lock
Synchronized internal lock and ReentrantLock are exclusive locks. Only one thread is allowed to execute a synchronized code block at a time. This ensures thread security, but the execution efficiency is low.
The ReentrantReadWriteLock read-write lock is an improved exclusive lock, also known as a shared/exclusive lock. Multiple threads are allowed to read the shared data simultaneously, but only one thread is allowed to update the shared data at a time.
Read/write locks Read and write locks are used to complete read and write operations. A thread must hold a read lock before reading shared data. The read lock can be held by multiple threads at the same time, that is, it is shared. A thread must hold a write lock before modifying the shared data. The write lock is exclusive. When one thread holds a write lock, other threads cannot obtain the corresponding lock.
A read lock is only shared between reader threads. When any thread holds the read lock, other threads cannot obtain the write lock. This ensures that no other thread updates the data during data reading.
For conditions | exclusive | role | |
---|---|---|---|
Read lock | The write lock is not held by any thread | Shared to the reader thread and exclusive to the writer thread | Multiple reader threads can read the shared data at the same time, ensuring that no other threads modify the shared data |
Write lock | The write lock is not held by any other thread, and the corresponding read lock is not held by any other thread | Either the reader thread or the writer thread is exclusive | Ensure that the writer thread modifies the shared data exclusively |
Read/write locks allow read sharing, read/write mutually exclusive, and write mutually exclusive.
In Java. Util. Concurrent. The locks in the package defines the ReadWriteLock interface, the interface defines readLock () returns to read locks, define writeLock write lock () method returns. The implementation class for this interface is ReentrantReadWriteLock.
Note that the readLock() and writeLock() methods return two different lock objects, not two different locks. The ReadWriteLock interface instance can play two roles. Other uses of read/write locks.
ReadWriteLock ReadWriteLock lock = new ReentrantReadWriteLock(); ReadLock = readLock. ReadLock (); // get writeLock Lock writeLock = rwlock. writeLock(); Readlock. lock(); Try {read shared data}finally{readlock. unlock(); // Always release the lock in the finally clause} // Write data writelock.lock (); // apply for writeLock try{update shared data}finally{writelock.unlock (); // Always release the lock in the finally clause}Copy the code
Read the Shared
The ReadWriteLock read/write lock enables multiple threads to read shared data at the same time, which improves the data read efficiency of programs.
package com.wkcto.lock.readwrite; import java.util.concurrent.TimeUnit; import java.util.concurrent.locks.ReadWriteLock; import java.util.concurrent.locks.ReentrantReadWriteLock; Public class Test01 {static class Service{// Define ReadWriteLock readWriteLock = new ReentrantReadWriteLock(); Public void read(){try {readwritelock.readlock ().lock(); System.out.println(thread.currentThread ().getName() + "--" + system.currentTimemillis ()); TimeUnit.SECONDS.sleep(3); } catch (InterruptedException e) {e.printStackTrace(); }finally { readWriteLock.readLock().unlock(); }} public static void main(String[] args) {Service Service = new Service(); // Create 5 threads and call the read() method for (int I = 0; i < 5; i++) { new Thread(new Runnable() { @Override public void run() { service.read(); // Call read() in the thread to read data}}).start(); } // After running the program, the multiple threads can acquire the lock read almost simultaneously, executing the code after lock()}}Copy the code
Write about a mutex
Only one thread is allowed to execute the code after lock() through the write lock in the ReadWriteLock read-write lock.
package com.wkcto.lock.readwrite; import java.util.concurrent.locks.ReadWriteLock; import java.util.concurrent.locks.ReentrantReadWriteLock; */ public class Test02 {static class Service{// Define ReadWriteLock first readWriteLock = new ReentrantReadWriteLock(); Public void write(){try {readWriteLock.writelock ().lock(); System.out.println(thread.currentThread ().getName() + "--" + system.currentTimemillis ()); Thread.sleep(3000); } catch (InterruptedException e) {e.printStackTrace(); }finally {system.out.println (thread.currentThread ().getName() + "" + system.currentTimemillis ()); readWriteLock.writeLock().unlock(); }} public static void main(String[] args) {Service Service = new Service(); For (int I = 0; i < 5; i++) { new Thread(new Runnable() { @Override public void run() { service.write(); // Call the method to modify the data}}).start(); } // Only one thread can acquire the write lock at a time}}Copy the code
Read and write the mutex
A write lock is an exclusive lock, and the reader thread and the writer thread are also mutually exclusive.
package com.wkcto.lock.readwrite; import java.util.concurrent.locks.Lock; import java.util.concurrent.locks.ReadWriteLock; import java.util.concurrent.locks.ReentrantReadWriteLock; /** * a thread acquires a read lock, while the writer thread waits; Public class Test03 {static class Service{ReadWriteLock ReadWriteLock = new ReentrantReadWriteLock(); Lock readLock = readWriteLock.readLock(); // Get read Lock Lock writeLock = readwritelock.writelock (); Public void read(){try {readlock. lock(); System.out.println(thread.currentThread ().getName() + "--" + system.currentTimemillis ()); Thread.sleep(3000); } catch (InterruptedException e) {e.printStackTrace(); }finally {system.out.println (thread.currentThread ().getName() + "" + system.currentTimemillis ()); readLock.unlock(); Public void write(){try {writelock.lock (); System.out.println(thread.currentThread ().getName() + "--" + system.currentTimemillis ()); Thread.sleep(3000); } catch (InterruptedException e) {e.printStackTrace(); }finally {system.out.println (thread.currentThread ().getName() + "" + system.currentTimemillis ()); writeLock.unlock(); }} public static void main(String[] args) {Service Service = new Service(); New Thread(new Runnable() {@override public void run() {service.read(); } }).start(); New Thread(new Runnable() {@override public void run() {service.write(); } }).start(); }}Copy the code