文档章节

架构师课程 3 - java lock

业余编程人士
 业余编程人士
发布于 2017/07/09 16:58
字数 638
阅读 14
收藏 0

锁 = 一堵墙

ReentrantLock:

private Lock lock = new ReentrantLock();
	
	public void method1(){
		try {
            // 上锁
			lock.lock();
			System.out.println("当前线程:" + Thread.currentThread().getName() + "进入method1..");
			Thread.sleep(1000);
			System.out.println("当前线程:" + Thread.currentThread().getName() + "退出method1..");
			Thread.sleep(1000);
		} catch (InterruptedException e) {
			e.printStackTrace();
		} finally {
			// 一定要解锁在finnally
			lock.unlock();
		}
	}
	
	public void method2(){
		try {
			lock.lock();
			System.out.println("当前线程:" + Thread.currentThread().getName() + "进入method2..");
			Thread.sleep(2000);
			System.out.println("当前线程:" + Thread.currentThread().getName() + "退出method2..");
			Thread.sleep(1000);
		} catch (InterruptedException e) {
			e.printStackTrace();
		} finally {
			
			lock.unlock();
		}
	}
	// 主方法
	public static void main(String[] args) {

		final UseReentrantLock ur = new UseReentrantLock();
		Thread t1 = new Thread(new Runnable() {
			@Override
			public void run() {
               // method1执行 method2就不能执行,因为上了锁,即使是多线程。
				ur.method1();
				ur.method2();
			}
		}, "t1");

		t1.start();
		try {
			Thread.sleep(10);
		} catch (InterruptedException e) {
			e.printStackTrace();
		}
		//System.out.println(ur.lock.getQueueLength());
	}

之前讲过 wait 和 notify必须配合syncronised 一起用才可以。 那么在reentrantlock这里就用Condition来代替。

	private Lock lock = new ReentrantLock();
	private Condition condition = lock.newCondition();
	
	public void method1(){
		try {
			lock.lock();
			System.out.println("当前线程:" + Thread.currentThread().getName() + "进入等待状态..");
			Thread.sleep(3000);
			System.out.println("当前线程:" + Thread.currentThread().getName() + "释放锁..");
			condition.await();	// Object wait,是释放锁
			System.out.println("当前线程:" + Thread.currentThread().getName() +"继续执行...");
		} catch (Exception e) {
			e.printStackTrace();
		} finally {
			lock.unlock();
		}
	}
	
	public void method2(){
		try {
			lock.lock();
			System.out.println("当前线程:" + Thread.currentThread().getName() + "进入..");
			Thread.sleep(3000);
			System.out.println("当前线程:" + Thread.currentThread().getName() + "发出唤醒..");
			condition.signal();		//=Object notify,不释放锁,所以他继续往下走,同事method1也继续走
            System.out.print("继续")
		} catch (Exception e) {
			e.printStackTrace();
		} finally {
			lock.unlock();
		}
	}
	
	public static void main(String[] args) {
		
		final UseCondition uc = new UseCondition();
		Thread t1 = new Thread(new Runnable() {
			@Override
			public void run() {
				uc.method1();
			}
		}, "t1");
		Thread t2 = new Thread(new Runnable() {
			@Override
			public void run() {
				uc.method2();
			}
		}, "t2");
		t1.start();

		t2.start();

一个lock可以创建many condition. 然后可以用signalAll()唤醒其他线程。

Lock lock = new ReentrantLock(boolean isfair)

fair lock : fist in , first lock . 默认是nonfair ,效率高。

------------------------------------------------------------------------------------------------------

ReentrantReadWriteLock : 在读多写少的情况下使用,读读共享,写写互斥,读写互斥。

private ReentrantReadWriteLock rwLock = new ReentrantReadWriteLock();
	private ReadLock readLock = rwLock.readLock();
	private WriteLock writeLock = rwLock.writeLock();
	
	public void read(){
		try {
			readLock.lock();
			System.out.println("当前线程:" + Thread.currentThread().getName() + "进入...");
			Thread.sleep(3000);
			System.out.println("当前线程:" + Thread.currentThread().getName() + "退出...");
		} catch (Exception e) {
			e.printStackTrace();
		} finally {
			readLock.unlock();
		}
	}
	
	public void write(){
		try {
			writeLock.lock(); // 比如 持久化操作
			System.out.println("当前线程:" + Thread.currentThread().getName() + "进入...");
			Thread.sleep(3000);
			System.out.println("当前线程:" + Thread.currentThread().getName() + "退出...");
		} catch (Exception e) {
			e.printStackTrace();
		} finally {
			writeLock.unlock();
		}
	}
	
	public static void main(String[] args) {
		
		final UseReentrantReadWriteLock urrw = new UseReentrantReadWriteLock();
		
		Thread t1 = new Thread(new Runnable() {
			@Override
			public void run() {
				urrw.read();
			}
		}, "t1");
		Thread t2 = new Thread(new Runnable() {
			@Override
			public void run() {
				urrw.read();
			}
		}, "t2");
		Thread t3 = new Thread(new Runnable() {
			@Override
			public void run() {
				urrw.write();
			}
		}, "t3");
		Thread t4 = new Thread(new Runnable() {
			@Override
			public void run() {
				urrw.write();
			}
		}, "t4");		
		
//		t1.start(); // 读读操作 t1 t2同事进入开始
//		t2.start();
		
//		t1.start(); // R 
//		t3.start(); // W // 读写互斥,t1 开始,t3不能动,只有t1完成 t3才自动运行开始写
		
		t3.start();
		t4.start(); // 写写也互斥

分布式锁自己手动实现很难:两台机器两个JVM不同步,要用zookeeper去实现分布式锁。

© 著作权归作者所有

业余编程人士
粉丝 5
博文 19
码字总数 9137
作品 0
其他
程序员
私信 提问
我们在谈高并发、分布式,其实都在谈什么?

2018年,互联网行业风起云涌,IT工程师如果仅凭传统开发思维,无法突破固有知识体系,终将会被社会所淘汰。既需要掌控整体又需要洞悉局部瓶颈并依据具体的业务场景给出解决方案的领导型人物—...

技术琐话
2018/06/20
0
0
裁员寒冬袭来,30岁还在CRUD的Java程序员,拿什么安身立命?

就在近日,智联招聘公布的数据更是侧面印证了很多公司“瘦身”的事实:“2018年第二季度,小微企业用人需求较第一季度平均下降26.6%”。 裁员大潮正滚滚向前,席卷各行各业! 你做好失业的准...

Java填坑之路
2018/10/16
20
0
没吃透 Netty 底层通讯原理,还能算的上 Java 老司机?

搞了N年Java,仍有不少朋友困惑:用了很多年Dubbo,觉得自己挺厉害,跳槽面试时一问RPC,一问底层通讯,一问NIO和AIO,就一脸懵逼,到底该怎么办? 画外音:大家有没有这样的感触?Dubbo用得...

ImportNew
01/09
0
0
作为一名java程序员你的薪资为什么上不去?

不管是开发、测试、运维,每个技术人员心里多多少少都有一个成为技术大牛的梦,毕竟“梦想总是要有的,万一实现了呢”!正是对技术梦的追求,促使我们不断地努力和提升自己。 很多人在问我,...

java高级架构牛人
2018/05/07
95
1
【直播回顾】阿里特邀专家徐雷Java Spring Boot开发实战系列课程(第18讲):制作Java Docker镜像与推送到DockerHub和阿里云Docker仓库

主讲人:徐雷(阿里云栖特邀Java专家) 徐雷,花名:徐雷frank;资深架构师,MongoDB中文社区联席主席,吉林大学计算机学士,上海交通大学硕士。从事了 10年+开发工作,专注于分布式架构,J...

李博bluemind
03/06
0
0

没有更多内容

加载失败,请刷新页面

加载更多

AliOS Things 3.0 应用开发指南

目录 应用开发框架介绍 使用条件 快速开始 第一步:下载AliOS Things 3.0源码 第二步:添加AOS_SDK_PATH环境变量 第三步:AliOS Studio中创建应用工程 编译、烧录、调试 其他说明 参考文档 ...

阿里云官方博客
40分钟前
3
0
日期和月份的计算

需求一 根据 【首次任务开始时间】和【任务间隔时间】和【每个任务持续时间】和【任务次数】计算出每个任务的时间 // 数据计算方法 async dateCalculation() { const firstD...

沉迷代码我爱学习
45分钟前
2
0
Spring Cloud Gateway 之请求坑位[微服务IP不同请求会失败]

问题产生背景 在使用Spring Cloud Gateway过程中,希望配置多Routes映射不同的微服务,因为Gateway 和Zuul的访问路径不同(zuul 会带有服务service Id),造成错误。 现象表现 问题定位 认为是...

IsaacZhang
56分钟前
5
0
Vue nodejs商城项目-搭建express框架环境

本文转载于:专业的前端网站➯Vue nodejs商城项目-搭建express框架环境 1.express-project 搭建express框架环境 安装express generator生成器 通过生成器自动创建项目 配置分析 安装 cnpm i -...

前端老手
今天
3
0
maven项目A引入maven项目B的jar包

首先打开 项目B 的 pom 文件,加入如下配置 <build> <plugins> <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-compiler-plugin<......

嘴角轻扬30
今天
3
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部