使用synchronized实现一个Lock代码详解

 更新时间:2017年12月19日 16:36:16   作者:三 丰  
这篇文章主要介绍了使用synchronized实现一个Lock代码详解,具有一定借鉴价值,需要的朋友可以参考下。

刚看到这个题目的时候无从下手,因为觉得synchronized和lock在加锁的方式上有很大不同,比如,看看正常情况下synchronized时如何加锁的。

方式一:

public synchronized void a(){ 
  //TODO 
} 

方式二:

public void b(){ 
  synchronized(this){ 
    //TODO 
  } 
} 

从这两种方式来看,锁都是加在{}之间的,我们再来看看Lock是如何做的呢:

public void c() { 
  lock.lock(); 
  try { 
    // TODO 
  } finally { 
    lock.unlock(); 
  } 
} 

这种方式的锁是加在lock()和unlock()之间的,所以要想实现一个lock功能,就要想怎么实现这样两个方法,lock()和unlock()方法,先定义一个框架如下所示:

public void lock(){
}
public void unlock(){
}

然后要想怎么用synchronized去实现这两个方法。

现在其实只是稍微清楚了一点思路,但是还不知道怎么去填充这两个方法,这是后再来分析一下Lock的加锁有什么特点,再来看看这段代码:

public void c() {
	lock.lock();
	//When current thread get the lock, other thread has to wait 
	try {
		//current thread get in the lock, other thread can not get in 
		// TODO
	}
	finally {
		lock.unlock();
		//current thread release the lock
	}
}

这段代码我只是加了一点注释,别的什么都没有做,是不是帮助理解这段代码,看看出现频率最高的词是什么,是currentthread,那么我们去填充lock()和unlock()方法的时候是不是注意要抓住currentthread这个关键字就可以找到解决方案呢?答案是肯定的。

接着分析,使用synchronized的时候如何让线程等待呢?是用wait()方法。怎么让线程唤醒呢,是用notify()方法。那么就要在lock()方法中使用wait()方法,在unlock()方法中使用notify()方法。那么我们在使用wait()和notify()的时候是有一个条件的,想想我们应该使用什么作为条件呢?

我们应该使用当前锁是否被占用作为判断条件,如果锁被占用,currentthread等待,想想我们在使用synchronized的时候是不是一直使用的这个条件,答案也是肯定的。

再来分析一下什么时候释放锁,使用什么作为条件,想想如果线程A拿到了锁,线程B能释放吗?当然不能,如果B能释放就违反了原则,当然不能。肯定是A线程的锁只能A来释放。所以判断条件就是判断持有锁的线程是不是currentthread,如果是的话,可以释放,不是的话当然不能。

现在来看看完整的代码:

package test.lock;
import java.util.Random;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.ThreadFactory;
public class NaiveLock {
	private static final long NONE = -1;
	private long owner = NONE;
	private Boolean isLooked() {
		return owner != NONE;
	}
	public synchronized void lock() {
		long currentThreadId = Thread.currentThread().getId();
		if (owner == currentThreadId) {
			throw new IllegalStateException("Lock has been acquired by current thread");
		}
		while (this.isLooked()) {
			System.out.println(String.format("thread %s is waitting lock", currentThreadId));
			try {
				wait();
			}
			catch (InterruptedException e) {
				e.printStackTrace();
			}
		}
		owner = currentThreadId;
		System.out.println(String.format("Lock is acquired by thread %s", owner));
	}
	public synchronized void unlock() {
		if (!this.isLooked() || owner != Thread.currentThread().getId()) {
			throw new IllegalStateException("Only Lock owner can unlock the lock");
		}
		System.out.println(String.format("thread %s is unlocking", owner));
		System.out.println();
		owner = NONE;
		notify();
	}
	public static void main(String[] args) {
		final NaiveLock lock = new NaiveLock();
		ExecutorService executor = Executors.newFixedThreadPool(20, new ThreadFactory() {
			private ThreadGroup group = new ThreadGroup("test thread group");
			{
				group.setDaemon(true);
			}
			@Override 
			      public Thread newThread(Runnable r) {
				return new Thread(group, r);
			}
		}
		);
		for (int i = 0; i < 20; i++) {
			executor.submit(new Runnable() {
				@Override 
				        public void run() {
					lock.lock();
					System.out.println(String.format("thread %s is running...", Thread.currentThread().getId()));
					try {
						Thread.sleep(new Random().nextint(1000));
					}
					catch (InterruptedException e) {
						e.printStackTrace();
					}
					lock.unlock();
				}
			}
			);
		}
	}
}

运行一下看看结果:

Lock is acquired by thread 8 
thread 8 is running... 
thread 27 is waitting lock 
thread 26 is waitting lock 
thread 25 is waitting lock 
thread 24 is waitting lock 
thread 23 is waitting lock 
thread 22 is waitting lock 
thread 21 is waitting lock 
thread 20 is waitting lock 
thread 19 is waitting lock 
thread 18 is waitting lock 
thread 17 is waitting lock 
thread 16 is waitting lock 
thread 15 is waitting lock 
thread 14 is waitting lock 
thread 13 is waitting lock 
thread 12 is waitting lock 
thread 11 is waitting lock 
thread 10 is waitting lock 
thread 9 is waitting lock 
thread 8 is unlocking 
 
Lock is acquired by thread 27 
thread 27 is running... 
thread 27 is unlocking 
 
Lock is acquired by thread 26 
thread 26 is running... 
thread 26 is unlocking 
 
Lock is acquired by thread 25 
thread 25 is running... 
thread 25 is unlocking 
 
Lock is acquired by thread 24 
thread 24 is running... 
thread 24 is unlocking 
 
Lock is acquired by thread 23 
thread 23 is running... 
thread 23 is unlocking 
 
Lock is acquired by thread 22 
thread 22 is running... 
thread 22 is unlocking 
 
Lock is acquired by thread 21 
thread 21 is running... 
thread 21 is unlocking 
 
Lock is acquired by thread 20 
thread 20 is running... 
thread 20 is unlocking 
 
Lock is acquired by thread 19 
thread 19 is running... 
thread 19 is unlocking 
 
Lock is acquired by thread 18 
thread 18 is running... 
thread 18 is unlocking 
 
Lock is acquired by thread 17 
thread 17 is running... 
thread 17 is unlocking 
 
Lock is acquired by thread 16 
thread 16 is running... 
thread 16 is unlocking 
 
Lock is acquired by thread 15 
thread 15 is running... 
thread 15 is unlocking 
 
Lock is acquired by thread 14 
thread 14 is running... 
thread 14 is unlocking 
 
Lock is acquired by thread 13 
thread 13 is running... 
thread 13 is unlocking 
 
Lock is acquired by thread 12 
thread 12 is running... 
thread 12 is unlocking 
 
Lock is acquired by thread 11 
thread 11 is running... 
thread 11 is unlocking 
 
Lock is acquired by thread 10 
thread 10 is running... 
thread 10 is unlocking 
 
Lock is acquired by thread 9 
thread 9 is running... 
thread 9 is unlocking 

如果把for循环改成30次,再看一下结果:

Lock is acquired by thread 8 
thread 8 is running... 
thread 27 is waitting lock 
thread 26 is waitting lock 
thread 25 is waitting lock 
thread 24 is waitting lock 
thread 23 is waitting lock 
thread 22 is waitting lock 
thread 21 is waitting lock 
thread 20 is waitting lock 
thread 19 is waitting lock 
thread 18 is waitting lock 
thread 17 is waitting lock 
thread 16 is waitting lock 
thread 15 is waitting lock 
thread 14 is waitting lock 
thread 13 is waitting lock 
thread 12 is waitting lock 
thread 11 is waitting lock 
thread 10 is waitting lock 
thread 9 is waitting lock 
thread 8 is unlocking 
 
Lock is acquired by thread 27 
thread 27 is running... 
thread 8 is waitting lock 
thread 27 is unlocking 
 
Lock is acquired by thread 27 
thread 27 is running... 
thread 26 is waitting lock 
thread 27 is unlocking 
 
Lock is acquired by thread 27 
thread 27 is running... 
thread 25 is waitting lock 
thread 27 is unlocking 
 
Lock is acquired by thread 24 
thread 24 is running... 
thread 27 is waitting lock 
thread 24 is unlocking 
 
Lock is acquired by thread 23 
thread 23 is running... 
thread 24 is waitting lock 
thread 23 is unlocking 
 
Lock is acquired by thread 22 
thread 22 is running... 
thread 23 is waitting lock 
thread 22 is unlocking 
 
Lock is acquired by thread 22 
thread 22 is running... 
thread 21 is waitting lock 
thread 22 is unlocking 
 
Lock is acquired by thread 22 
thread 22 is running... 
thread 20 is waitting lock 
thread 22 is unlocking 
 
Lock is acquired by thread 22 
thread 22 is running... 
thread 19 is waitting lock 
thread 22 is unlocking 
 
Lock is acquired by thread 22 
thread 22 is running... 
thread 18 is waitting lock 
thread 22 is unlocking 
 
Lock is acquired by thread 17 
thread 17 is running... 
thread 17 is unlocking 
 
Lock is acquired by thread 16 
thread 16 is running... 
thread 16 is unlocking 
 
Lock is acquired by thread 15 
thread 15 is running... 
thread 15 is unlocking 
 
Lock is acquired by thread 14 
thread 14 is running... 
thread 14 is unlocking 
 
Lock is acquired by thread 13 
thread 13 is running... 
thread 13 is unlocking 
 
Lock is acquired by thread 12 
thread 12 is running... 
thread 12 is unlocking 
 
Lock is acquired by thread 11 
thread 11 is running... 
thread 11 is unlocking 
 
Lock is acquired by thread 10 
thread 10 is running... 
thread 10 is unlocking 
 
Lock is acquired by thread 9 
thread 9 is running... 
thread 9 is unlocking 
 
Lock is acquired by thread 8 
thread 8 is running... 
thread 8 is unlocking 
 
Lock is acquired by thread 26 
thread 26 is running... 
thread 26 is unlocking 
 
Lock is acquired by thread 25 
thread 25 is running... 
thread 25 is unlocking 
 
Lock is acquired by thread 27 
thread 27 is running... 
thread 27 is unlocking 
 
Lock is acquired by thread 24 
thread 24 is running... 
thread 24 is unlocking 
 
Lock is acquired by thread 23 
thread 23 is running... 
thread 23 is unlocking 
 
Lock is acquired by thread 21 
thread 21 is running... 
thread 21 is unlocking 
 
Lock is acquired by thread 20 
thread 20 is running... 
thread 20 is unlocking 
 
Lock is acquired by thread 19 
thread 19 is running... 
thread 19 is unlocking 
 
Lock is acquired by thread 18 
thread 18 is running... 
thread 18 is unlocking 

总结

以上就是本文关于使用synchronized实现一个Lock代码详解的全部内容,希望对大家有所帮助。感兴趣的朋友可以继续参阅本站:

Java线程同步Lock同步锁代码示例

Java编程synchronized与lock的区别【推荐】

Java多线程之readwritelock读写分离的实现代码

如有不足之处,欢迎留言指出。感谢朋友们对本站的支持!

相关文章

  • Spring Boot快速搭建Spring框架教程

    Spring Boot快速搭建Spring框架教程

    这篇文章主要为大家详细介绍了Spring Boot快速搭建Spring框架教程,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2017-10-10
  • Spring data jpa的使用与详解(复杂动态查询及分页,排序)

    Spring data jpa的使用与详解(复杂动态查询及分页,排序)

    这篇文章主要介绍了Spring data jpa的使用与详解(复杂动态查询及分页,排序),文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2020-11-11
  • spring cloud实现Eureka注册中心的HA的方法

    spring cloud实现Eureka注册中心的HA的方法

    本篇文章主要介绍了spring cloud实现Eureka注册中心的HA的方法,小编觉得挺不错的,现在分享给大家,也给大家做个参考。一起跟随小编过来看看吧
    2018-01-01
  • Java中HashMap如何解决哈希冲突

    Java中HashMap如何解决哈希冲突

    本文主要介绍了Java中HashMap如何解决哈希冲突,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2022-05-05
  • java实现哈夫曼压缩的实例

    java实现哈夫曼压缩的实例

    这篇文章主要介绍了java实现哈夫曼压缩的实例的相关资料,需要的朋友可以参考下
    2017-07-07
  • Java实现map转换成json的方法详解

    Java实现map转换成json的方法详解

    这篇文章主要为大家详细介绍了Java语言实现map转换成json的几种方法,文中的示例代码讲解详细,对我们学习Java有一定帮助,需要的可以参考一下
    2022-05-05
  • java使用JMF实现音乐播放功能

    java使用JMF实现音乐播放功能

    这篇文章主要为大家详细介绍了java使用JMF实现音乐播放的相关资料,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2017-06-06
  • Java判断是否为闰年的方法示例

    Java判断是否为闰年的方法示例

    这篇文章主要介绍了Java判断是否为闰年的方法示例,本文直接给出示例代码,并讲解了判断原理,需要的朋友可以参考下
    2015-06-06
  • JDBC获取数据库连接的5种方式实例

    JDBC获取数据库连接的5种方式实例

    JDBC是一种用于执行SQL语句的JavaAPI,为多种关系数据库提供统一访问,它由一组用Java语言编写的类和接口组成,提供了诸如查询和更新数据库中数据的方法,这篇文章主要给大家介绍了关于JDBC获取数据库连接的5种方式,需要的朋友可以参考下
    2022-06-06
  • 以Java Web项目为例浅谈前后端分离开发模式

    以Java Web项目为例浅谈前后端分离开发模式

    这篇文章主要介绍了以Java Web项目为例浅谈前后端分离开发模式,文章围绕主题展开详细的内容介绍,具有一定的参考价值,需要的小伙伴可以参考一下
    2022-08-08

最新评论