Java_175_Thread_可重入锁_不可重入锁_synchronized不可中断_ReentrantLock可中断

可重入锁

package TCPUDPThread;

import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.CopyOnWriteArrayList;

/**
 * 可重入锁
 * 锁作为并发共享数据保证一致性的工具,大多数内置锁都是可重入的,也就是说,如果某个线程试图获取一个已经由它自己持有的锁时,那么这个请求会立刻成功,并且将这个锁的计数值加1,而当线程退出同步代码块时,计数器将会递减,当计数值等于0时,锁释放.
 * 如果没有可重入锁的支持,在第二次企图获得锁时将会进入死锁状态.可重入锁随处可见
 *
 * 可重入锁,锁可以延续使用
 */
/**
 * 可重入锁演示
 * @author pmc
 *
 */
public class synchronizedTest16 {
	public synchronized void a(){
		System.out.println("a()");
	}
	public synchronized void b(){
		System.out.println("b()");
	}
	/**
	 * 可重入锁用法
	 */
	public synchronized void all(){
		a();
		b();
	}
	public static void main(String[] args) {
		new Thread(()->{
			//第一次获得锁
			synchronized(synchronizedTest16.class){
				while(true){
					System.out.println("1");
					//第二次获得同样的锁
					synchronized(synchronizedTest16.class){
						System.out.println("2");
					}
					try {
						Thread.sleep(1000);
					} catch (InterruptedException e) {
						e.printStackTrace();
					}
				}
			}
		}).start();
		
		synchronizedTest16 t6=new synchronizedTest16();
		t6.all();
	}
}


不可重入改可重入/ReentrantLock 

package TCPUDPThread;

import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.CopyOnWriteArrayList;

/**
 * 可重入锁
 * 锁作为并发共享数据保证一致性的工具,大多数内置锁都是可重入的,也就是说,如果某个线程试图获取一个已经由它自己持有的锁时,那么这个请求会立刻成功,并且将这个锁的计数值加1,而当线程退出同步代码块时,计数器将会递减,当计数值等于0时,锁释放.
 * 如果没有可重入锁的支持,在第二次企图获得锁时将会进入死锁状态.可重入锁随处可见
 *
 * 可重入锁,锁可以延续使用
 */
/**
 * 可重入锁演示
 * @author pmc
 *
 */
public class synchronizedTest15 {
//ReentrantLock lock=new ReentrantLock();
	ReLock lock=new ReLock();
	public void a() throws Exception{
		lock.lock();
		b();
		lock.unlock();
	}
	public void b() throws Exception{
		lock.lock();
		System.out.println("B");
		lock.unlock();
	}
	public static void main(String[] args) throws Exception {
		synchronizedTest15 test=new synchronizedTest15();
		test.a();
	}
}
/**
 *//**改为重入锁代码
 * @author pmc
 *
 */
class ReLock{
	//是否占用
	private boolean isLockde=false;
	Thread locked=null;//存储线程**
	private int count=0;//**
	//使用锁
	public synchronized void lock() throws Exception{
		Thread t=Thread.currentThread();//**
		while(isLockde&&locked!=t){//**
			System.out.println(isLockde);
			System.out.println("1");
			wait();
			System.out.println("2");
		}
		isLockde=true;
		locked=t;//**
		count++;//**
	}
	//释放锁
	public synchronized void unlock(){
		if(Thread.currentThread()==locked){//**
			count--;//**
			if(count==0){//**
				isLockde=false;
				notify();
				locked=null;
			}
		}
	}
}

ReentrantLock常常对比着synchronized

(1)synchronized是独占锁,加锁和解锁的过程自动进行,易于操作,但不够灵活。ReentrantLock也是独占锁,加锁和解锁的过程需要手动进行,不易操作,但非常灵活。

(2)synchronized可重入,因为加锁和解锁自动进行,不必担心最后是否释放锁;ReentrantLock也可重入,但加锁和解锁需要手动进行,且次数需一样,否则其他线程无法获得锁。

(3)synchronized不可响应中断,一个线程获取不到锁就一直等着;ReentrantLock可以相应中断。

ReentrantLock好像比synchronized关键字没好太多,我们再去看看synchronized所没有的,一个最主要的就是ReentrantLock还可以实现公平锁机制。什么叫公平锁呢?也就是在锁上等待时间最长的线程将获得锁的使用权。通俗的理解就是谁排队时间最长谁先执行获取锁。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Mr_Pmc

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值