java并发编程实战-21-手动写一个可重入锁---二周目

这个代码保证value++的原子性。

 自己实现一把锁:

  为什么不支持重入?这个是mylock老的代码。这个while当作if去解读就可以了。

解锁了。

多线程去执行

在Demo中测试重入。

package com.roocon.thread.ta1;

import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;

public class Demo {
	
	//Lock lock = new ReentrantLock();
	Lock lock = new MyLock();
	
	public void a() {
		lock.lock();
		System.out.println("a");
		b();
		lock.unlock();
	}
	
	public void b() {
		lock.lock();
		System.out.println("b");
		c();
		lock.unlock();
	}
	
	public void c() {
		lock.lock();
		System.out.println("c");
		lock.unlock();
	}
	
	public static void main(String[] args) {
		Demo d = new Demo();
		
		new Thread(new Runnable() {
			
			@Override
			public void run() {
				d.a();
			}
		}).start();
		
//		new Thread(new Runnable() {
//			
//			@Override
//			public void run() {
//				d.b();
//			}
//		}).start();
		
	}

}

 介绍了检测死锁的工具。

wait是在sy的对象上等待,就是mylock对象。

什么时候释放锁:

任何线程进入同步代码块、同步方法之前,必须获得同步监视器的锁定,那么何时会释放这个锁定呢?在程序中,是无法显式释放对同步监视器的锁的,而会在如下几个情况下释放锁。

1、当前线程的同步方法、代码块执行结束的时候释放

2、当前线程在同步方法、同步代码块中遇到break 、 return 终于该代码块或者方法的时候释放。

3、。。。。出现未处理的error或者exception导致异常结束的时候释放

4、。。。。程序执行了 同步对象 wait 方法 ,当前线程暂停,释放锁

==============================================================如下情况不会释放锁=====================================

1、。。。。。。程序调用 Thread.sleep()  Thread.yield() 这些方法暂停线程的执行,不会释放。

2、线程执行同步代码块时,其他线程调用 suspend 方法将该线程挂起,该线程不会释放锁 ,所以我们应该避免使用 suspend 和 resume 来控制线程

关于wait和notify:https://blog.csdn.net/djzhao/article/details/79410229

自己实现的锁的代码:

package com.roocon.thread.ta1;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.Lock;
public class MyLock implements Lock {
	private boolean isLocked = false;
	private Thread lockBy = null;
	private int lockCount = 0;
	@Override
	public synchronized void lock() {
		Thread currentThread = Thread.currentThread(); // Thread-0
		while (isLocked && currentThread != lockBy)//已经被锁住了并且当前的线程不是锁的线程
			try {
				wait();
			} catch (InterruptedException e) {
				e.printStackTrace();
			}
		isLocked = true;
		lockBy = currentThread;
		lockCount ++; // 1   2
	}
	@Override
	public synchronized void unlock() {
		if(lockBy == Thread.currentThread()) {
			lockCount --;  // 1  0
			
			if(lockCount == 0) {
				notify();
				isLocked = false;
			}
		}
	}
	@Override
	public void lockInterruptibly() throws InterruptedException {
		
	}
	@Override
	public boolean tryLock() {
		return false;
	}
	@Override
	public boolean tryLock(long time, TimeUnit unit) throws InterruptedException {
		// TODO Auto-generated method stub
		return false;
	}
	@Override
	public Condition newCondition() {
		// TODO Auto-generated method stub
		return null;
	}
}

业务多个线程同时调用

package com.roocon.thread.ta1;

public class Sequence {

	private MyLock lock = new MyLock();

	private int value;

	public int getNext() {
		lock.lock();
		value++;
		lock.unlock();
		return value;

	}
	
	public static void main(String[] args) {
		
		Sequence s = new Sequence();
		
		new Thread(new Runnable() {
			
			@Override
			public void run() {
				while(true)
				System.out.println(s.getNext());
			}
		}).start();
		new Thread(new Runnable() {
			
			@Override
			public void run() {
				while(true)
				System.out.println(s.getNext());
			}
		}).start();
		new Thread(new Runnable() {
			
			@Override
			public void run() {
				while(true)
				System.out.println(s.getNext());
			}
		}).start();
		new Thread(new Runnable() {
			
			@Override
			public void run() {
				while(true)
				System.out.println(s.getNext());
			}
		}).start();
		new Thread(new Runnable() {
			
			@Override
			public void run() {
				while(true)
				System.out.println(s.getNext());
			}
		}).start();
	}

}

 测试可重入的锁的代码。

package com.roocon.thread.ta1;

import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;

public class Demo {
	
	//Lock lock = new ReentrantLock();
	Lock lock = new MyLock();
	
	public void a() {
		lock.lock();
		System.out.println("a");
		b();
		lock.unlock();
	}
	
	public void b() {
		lock.lock();
		System.out.println("b");
		c();
		lock.unlock();
	}
	
	public void c() {
		lock.lock();
		System.out.println("c");
		lock.unlock();
	}
	
	public static void main(String[] args) {
		Demo d = new Demo();
		
		new Thread(new Runnable() {
			
			@Override
			public void run() {
				d.a();
			}
		}).start();
		
//		new Thread(new Runnable() {
//			
//			@Override
//			public void run() {
//				d.b();
//			}
//		}).start();
		
	}

}

 底层是synchronized和wait和notify实现的。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值