比较 synchronized和Reentrantlock

1、级别不同:

Synchronized是java的一个关键字,用于对所修饰的区域加锁,实现线程同步;

ReenTrantLock是java提供的一个实现加锁的类,也可以实现线程同步。

2、重入锁:

SynchronizedReentrantLock都是重入锁

3、锁对象:

(1)synchronized:

Synchronized可以修饰方法、代码块等,可以指定锁对象,在修饰方法时,也可以不指定锁对象,当不指定锁对象时,但在修饰代码块时要求指定锁对象;

当修饰静态方法时,如果不指定锁对象,则锁是当前类;

当修饰非静态方法时,如果不指定锁对象,则锁是当前对象实例。

(2)ReentrantLock:

由创建的ReentrantLock对象调用方法实现加锁解锁

4、ReentrantLock的优势:

ReentrantLock用途和synchronized相同,只是ReentrantLock更加灵活

       1、ReentrantLock需要使用相应方法进行加锁解锁,使用lock()加锁,使用unlock()解锁,unlock()经常写在finally中;

2、可以使用tryLock()进行尝试获得锁,如果获得锁失败,返回false,获得成功返回true,这使得线程不用在请求锁的时候一直处于等待状态,可以根据是否获得锁,相应地去做下一步的逻辑;

3、ReentrantLock可以设置为公平锁: new ReentrantLock(true);默认为非公平锁 new ReentrantLock(false)或者new ReentrantLock( )结果是一样的;

 

4、可以使用LockInterruptibly( )控制一直处于等待锁状态的线程,可以将一个一直等待锁对象,但是无法获得锁的线程中断掉。

 

LockInterruptibly( )使用方法:

场景: 线程1持有锁,线程2一直等待获得锁,为了让线程2不再等待,将线程2中断掉

import java.util.concurrent.locks.ReentrantLock;

public class ReentrantLockInterruptiblyTest {
	public static void main(String[] args) {
		ReentrantLock lock = new ReentrantLock();
		
		
		Thread thread1 = new Thread(new Runnable() {

			@Override
			public void run() {
				lock.lock();
				try {
					System.out.println("线程1持有锁,不想释放锁");
					Thread.sleep(500);
					System.out.println("线程1持有锁,不想释放锁");
				} catch (InterruptedException e) {
					e.printStackTrace();
				} finally {
					lock.unlock();
					System.out.println("线程1释放锁");
				}
			}
			
		});
		
		Thread thread2 = new Thread(new Runnable() {

			@Override
			public void run() {
				System.out.println("线程2请求锁,不能获得锁");
				try {
					lock.lockInterruptibly();
					try {
						System.out.println("线程2持有锁,不想释放锁");
						Thread.sleep(5000);
					} catch (InterruptedException e) {
						e.printStackTrace();
					} finally {
						lock.unlock();
					}
				} catch (InterruptedException e1) {
					e1.printStackTrace();
					System.out.println("线程2获得锁失败");
				}
				
			}
			
		});
		thread1.start();
		thread2.start();
		//在主线程中将等待获得锁对象的线程2中断掉
		thread2.interrupt();
	}
}

执行结果:比较 synchronized和Reentrantlock_第1张图片

发现:当线程1持有锁,而线程2持续等待锁时,在主线程中  thread2.interruptibly( );将线程2直接中断掉了。

 

 

 

 

 

 

你可能感兴趣的:(java,多线程,并发编程,thread)