Simple exercise using the synchronized keyword and the Lock interface

synchronized

use of package lock;

import java.text.SimpleDateFormat;
import java.util.Date;

public class MySynchronized {
	
	static String now() {
		SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
		Date d = new Date();
		String now = sdf.format(d);
		//time of return
		return now;
	}
	//log method
	static void log(String msg) {
		System.out.printf("%s:%s%s%n",now(),Thread.currentThread().getName(),msg);
	}
	public static void main(String[] args) {
		final Object someObject = new Object();
		
		Thread t1 = new Thread() {
			@Override
			public void run() {
				// progress description
				log("Thread has been running");
				log("Thread tried to own someObject");
				//sync object
				synchronized (someObject) {//synchronized The code in the synchronized code block is the key logic code and needs to be protected to avoid generating dirty data
					log("Thread owns someObject");
					try {
						Thread.sleep(5000);
					} catch (InterruptedException e) {
						// TODO Auto-generated catch block
						e.printStackTrace ();
					}
					log("release someObject");
				}
			}
		};
		t1.setName("T1");//Set the name
		t1.start();
		
		Thread t2 = new Thread() {
			@Override
			public void run() {
				// progress description
				log("Thread has been running");
				log("Thread tried to own someObject");
				//sync object
				synchronized (someObject) {
					log("Thread owns someObject");
					try {
						Thread.sleep(5000);
					} catch (InterruptedException e) {
						// TODO Auto-generated catch block
						e.printStackTrace ();
					}
					log("release someObject");
				}
			}
		};
		t2.setName("T2");
		t2.start();
	}
}

Lock interface

use of package lock;

import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;

public class TestMyLock {
	//time
	static String now() {
		SimpleDateFormat sdf = new SimpleDateFormat();
		Date d = new Date();
		String now = sdf.format(d);
		return now;
	}
	
	// Simplified description
	static void log(String msg) {
		System.out.printf("%s:%s%s%n",now(),Thread.currentThread().getName(),msg);
	}
	
	public static void main(String[] args) {
		Lock lock = new ReentrantLock();
		
		Thread t1 = new Thread() {
			@Override
			public void run() {
				log("Thread has been running");
				log("Thread tried to hold lock");
				lock.lock();
				log("Thread successfully holds lock");
				try {
					Thread.sleep(5000);
				} catch (InterruptedException e) {
					// TODO Auto-generated catch block
					e.printStackTrace ();
				}finally {
					log("Thread end");
					//turn off lock
					lock.unlock();
				}
			}
		};
		t1.setName("T1");
		t1.start();
		
		try {
			// let t1 fly for two seconds
			Thread.sleep(2000);
		} catch (InterruptedException e1) {
			// TODO Auto-generated catch block
			e1.printStackTrace();
		}
		
		Thread t2 = new Thread() {
			@Override
			public void run() {
				log("Thread has been running");
				log("Thread tried to hold lock");
				lock.lock();//The code between lock.lock() and lock.unlock() is the key logic code and needs to be protected to avoid generating dirty data
				log("Thread successfully holds lock");
				try {
					Thread.sleep(5000);
				} catch (InterruptedException e) {
					// TODO Auto-generated catch block
					e.printStackTrace ();
				}finally {
					log("Thread end");
					//turn off lock
					lock.unlock();
				}
			}
		};
		t2.setName("T2");
		t2.start();
	}
}

tyyLock() usage

use of package lock;

import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;

public class TestMyTrylock {
	//time
	static String now() {
		SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
		Date d = new Date();
		String now = sdf.format(d);
		return now;
	}
	// normalized output
	static void log(String msg) {
		
		System.out.printf("%s:%s%s%n",now(),Thread.currentThread().getName(),msg);
	}
	public static void main(String[] args) {
		Lock lock = new ReentrantLock();
		
		
		Thread t1 = new Thread() {
			@Override
			public void run() {
				boolean locked = false;//Record whether the thread occupies the successful lock object
				log("Thread has been running");
				log("Thread view holds lock object");
				try {
					//Set the maximum waiting time of the thread to two seconds
					loked = lock.tryLock(2,TimeUnit.SECONDS);
					if(loked) {
						log("The thread occupies the lock object and performs operations for 5 seconds");
						Thread.sleep(5000);
					}else {
						log("The thread failed to occupy the lock object after two seconds of effort");
					}
					log("Thread end");
				} catch (InterruptedException e) {
					// TODO Auto-generated catch block
					e.printStackTrace ();
				}finally {
					if(loked) {
						lock.unlock();
					}
				}
			}
		};
		t1.setName("T1");
		t1.start();
		
		Thread t2 = new Thread() {
			@Override
			public void run() {
				boolean locked = false;//Record whether the thread occupies the successful lock object
				log("Thread has been running");
				log("Thread view holds lock object");
				try {
					loked = lock.tryLock(2,TimeUnit.SECONDS);
					if(loked) {
						log("The thread occupies the lock object and performs operations for 5 seconds");
						Thread.sleep(5000);
					}else {
						log("The thread failed to occupy the lock object after two seconds of effort");
					}
					log("Thread end");
				} catch (InterruptedException e) {
					// TODO Auto-generated catch block
					e.printStackTrace ();
				}finally {
					if(loked) {
						lock.unlock();
					}
				}
			}
		};
		t2.setName("T2");
		t2.start();
	}
}

Thread interaction using lock

use of package lock;

import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;

public class TestMyLock {
	//time
	static String now() {
		SimpleDateFormat sdf = new SimpleDateFormat();
		Date d = new Date();
		String now = sdf.format(d);
		return now;
	}
	
	// Simplified description
	static void log(String msg) {
		System.out.printf("%s:%s%s%n",now(),Thread.currentThread().getName(),msg);
	}
	
	public static void main(String[] args) {
		Lock lock = new ReentrantLock();
		//The lock is released later, and the following class needs to be used to wake up other threads
        Condition condition = lock.newCondition();
        
		Thread t1 = new Thread() {
			@Override
			public void run() {
				log("Thread has been running");
				log("Thread tried to hold lock");
				lock.lock();
				log("Thread successfully holds lock");
				try {
					Thread.sleep(5000);
					
					//Let the thread temporarily release the lock and let other threads get the lock object and run
                    //The release method using lock here is slightly different from synchronized
                    log("Thread temporarily releases lock");
                    condition.await();//The release operation corresponds to the synchronized wait()
                    log("The thread regains the lock object for five seconds of operation");
                    Thread.sleep(5000);
				} catch (InterruptedException e) {
					// TODO Auto-generated catch block
					e.printStackTrace ();
				}finally {
					log("Thread end");
					//turn off lock
					lock.unlock();
				}
			}
		};
		t1.setName("T1");
		t1.start();
		
		try {
			//Let t1 run for two seconds first
			Thread.sleep(2000);
		} catch (InterruptedException e1) {
			// TODO Auto-generated catch block
			e1.printStackTrace();
		}
		
		Thread t2 = new Thread() {
			@Override
			public void run() {
				log("Thread has been running");
				log("Thread tried to hold lock");
				lock.lock();//The code between lock.lock() and lock.unlock() is the key logic code and needs to be protected to avoid generating dirty data
				log("The thread successfully holds the lock and operates for 5 seconds");
				try {
					Thread.sleep(5000);
					condition.signal();//The wake-up operation corresponds to the synchronized notify() and there are signalAll() and notifyAll();
				} catch (InterruptedException e) {
					// TODO Auto-generated catch block
					e.printStackTrace ();
				}finally {
					log("Thread end");
					//turn off lock
					lock.unlock();
				}
			}
		};
		t2.setName("T2");
		t2.start();
	}
}

Briefly describe the difference between the synchronized keyword and the Lock interface

The former is the java keyword is a built-in language implementation, the latter is an interface, and then the lock needs to be manually released at each end, otherwise it will cause a deadlock, and the use of synchronized is easy to cause a deadlock, and the code must be logically rigorous and error-free to avoid deadlock. Lock, and lock has a trylock() method that can set the time to preempt resources. After the time is passed, it will not be preempted automatically, effectively avoiding deadlock, and then the thread interaction in synchronized, which is occupied by calling wait(), notify(), notifyAll( ) are from the Object super parent class. The use of await(), signal(), and signalAll() in the lock interface comes from the Condition interface;

Guess you like

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