The code copy is as follows:
package com.yao;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Future;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReadWriteLock;
import java.util.concurrent.locks.ReentrantLock;
import java.util.concurrent.locks.ReentrantReadWriteLock;
/**
* Lockers
* An important concept in multi-threaded programming is locking. If a resource is shared by multiple threads, in order to ensure the integrity of the data,
* When performing transactional operations, the shared resource needs to be locked, which ensures that only one thread can operate on the resource when performing transactional operations.
* This ensures the integrity of the data. Prior to 5.0, the locking function was implemented by the Synchronized keyword.
*/
public class Lockers {
/**
* Test the use of Lock. Using Lock in the method can avoid using the Synchronized keyword.
*/
public static class LockTest {
Lock lock = new ReentrantLock();// Lock
double value = 0d; // Value
int addtimes = 0;
/**
* Increase the value of value. The operation of this method is divided into 2 steps and is interdependent and must be implemented in a transaction.
* So the method must be synchronized, the previous practice was to use the Synchronized keyword in the method declaration.
*/
public void addValue(double v) {
lock.lock();// Obtain the lock
System.out.println("LockTest to addValue: " + v + " "
+ System.currentTimeMillis());
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
}
this.value += v;
this.addtimes++;
lock.unlock();// Release the lock
}
public double getValue() {
return this.value;
}
}
public static void testLockTest() throws Exception{
final LockTest lockTest = new LockTest();
// Create a new task 1 and call the addValue method of lockTest
Runnable task1 = new Runnable(){
public void run(){
lockTest.addValue(55.55);
}
};
// Create new task 2 and call lockTest's getValue method
Runnable task2 = new Runnable(){
public void run(){
System.out.println("value: " + lockTest.getValue());
}
};
// Create a new task execution service
ExecutorService cachedService = Executors.newCachedThreadPool();
Future future = null;
// Execute task 1 three times at the same time. Since the addValue method uses a lock mechanism, it will be executed in sequence in essence.
for (int i=0; i<3; i++){
future = cachedService.submit(task1);
}
// Wait for the last task 1 to be executed
future.get();
// Execute task 2 again to output the result
future = cachedService.submit(task2);
// After waiting for task 2 to be executed, close the task execution service
future.get();
cachedService.shutdownNow();
}
/**
* ReadWriteLock has two built-in Locks, one is the read Lock and the other is the written Lock.
* Multiple threads can get read locks at the same time, but only one thread can get written locks.
* And after the written Lock is locked, no thread can get the Lock. The methods provided by ReadWriteLock are:
* readLock(): Returns a read lock
* writeLock(): Returns a written lock, this lock is exclusive.
* ReadWriteLockTest is very suitable for handling read and write operations of similar files.
* You can read at the same time when reading, but you cannot write; you cannot write at the same time or read at the same time when writing.
*/
public static class ReadWriteLockTest{
// Lock
ReadWriteLock lock = new ReentrantReadWriteLock();
// Value
double value = 0d;
int addtimes = 0;
/**
* Increase the value of value, and do not allow multiple threads to enter the method at the same time.
*/
public void addValue(double v) {
// Get writeLock and lock
Lock writeLock = lock.writeLock();
writeLock.lock();
System.out.println("ReadWriteLockTest to addValue: " + v + " "
+ System.currentTimeMillis());
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
}
try {
// Do the writing work
this.value += v;
this.addtimes++;
} finally {
// Release the writeLock lock
writeLock.unlock();
}
}
/**
* Get information. When a thread is calling the addValue method, the information obtained by getInfo may be incorrect.
* Therefore, it is also necessary to ensure that when the method is called, no method is calling the addValue method.
*/
public String getInfo() {
// Get readLock and lock
Lock readLock = lock.readLock();
readLock.lock();
System.out.println("ReadWriteLockTest to getInfo"
+ System.currentTimeMillis());
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
}
try {
// Do the reading work
return this.value + " : " + this.addtimes;
} finally {
// Release readLock
readLock.unlock();
}
}
}
public static void testReadWriteLockTest() throws Exception{
final ReadWriteLockTest readWriteLockTest = new ReadWriteLockTest();
// Create a new task 1 and call the addValue method of lockTest
Runnable task_1 = new Runnable(){
public void run(){
readWriteLockTest.addValue(55.55);
}
};
// Create new task 2 and call lockTest's getValue method
Runnable task_2 = new Runnable(){
public void run(){
System.out.println("info: " + readWriteLockTest.getInfo());
}
};
// Create a new task execution service
ExecutorService cachedService_1 = Executors.newCachedThreadPool();
Future future_1 = null;
// Execute 5 tasks at the same time, of which the first 2 tasks are task_1 and the last two tasks are task_2
for (int i=0; i<2; i++){
future_1 = cachedService_1.submit(task_1);
}
for (int i=0; i<2; i++){
future_1 = cachedService_1.submit(task_2);
}
// The last task is task_1
future_1 = cachedService_1.submit(task_1);
// The execution order of these 5 tasks should be:
// The first task_1 is executed first, and the second task_1 is executed again; this is because it cannot be written at the same time, so you must wait.
// Then two task_2 are executed at the same time; this is because when writing, you cannot read it, so you wait for the end of writing.
// Because they can be read at the same time, they are executed at the same time
// The last task_1 is executed again. This is because you cannot write when reading, so you must wait until the reading is over before you can write.
// Wait for the last task_2 to be executed
future_1.get();
cachedService_1.shutdownNow();
}
public static void main(String[] args) throws Exception{
Lockers.testLockTest();
System.out.println("---------------------");
Lockers.testReadWriteLockTest();
}
}