锁对象

临界区:临界区是一个特殊的代码段,该代码段访问某种特殊的公共资源,该资源同一时间只允许一个线程使用。

Java中可以使用锁对象创造一个临界区:

 myLock.lock();
try {
关键代码
} finally {
myLock.unlock();
}

使用这种结构可以确保关键代码不会同时被多个线程执行,线程想要执行关键代码必须先获取“锁”,“锁”只能被一个线程持有,在该线程将“锁”释放前,其他线程因为获取不到锁而被阻塞,“锁”被释放的时候,之前因为获取这个锁被挂起的线程都会被唤醒,共同竞争着去获取锁。

将释放锁的操作写在finally里是很重要的,防止某个线程执行关键代码的时候因为抛出异常而没有将锁释放。

 package learnspringboot.xiao.learnjava.thread;

 import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock; /**
* @author xzy
* @date 2019-12-13 11:01
* 说明:模拟银行转账
*/
public class Bank {
private Map<String, Double> accountMap = new HashMap<>();
private Lock myLock = new ReentrantLock();
private Condition haveMoney = myLock.newCondition(); public Bank() {
this.accountMap.put("ZhangSan", 100.0);
this.accountMap.put("WangWu", 1000.0);
} public void transfer(String from, String to, Double money) {
//线程执行后面的代码段需要先获得锁,获取不到就挂起。
myLock.lock();
System.out.println("当前获得锁的线程:" + Thread.currentThread().getName());
System.out.println(from + "想给" + to + "转" + money + "元," + from + "现在有" + accountMap.get(from) + "元");
try {
while (accountMap.get(from) < money) {
System.out.println("线程阻塞:" + Thread.currentThread().getName());
//获取到锁的线程需要等待本条件成立,条件成立前将锁释放,线程阻塞。
haveMoney.await();
}
accountMap.put(from, accountMap.get(from) - money);
accountMap.put(to, accountMap.get(to) + money);
System.out.println(from + "转给" + to + money + "元 线程:" + Thread.currentThread().getName());
//通知因本条件而挂起的线程,条件现在可能已经满足,可以试着再去获取肯看。
haveMoney.signalAll();
} catch (Exception e) {
e.printStackTrace();
} finally {
myLock.unlock();
}
} public static void main(String[] args) {
Bank bank = new Bank();
Thread thread1 = new Thread(() -> {
bank.transfer("ZhangSan", "WangWu", 500.0);
});
Thread thread2 = new Thread(() -> {
bank.transfer("WangWu", "ZhangSan", 1000.0);
});
Thread thread3 = new Thread(() -> {
bank.transfer("ZhangSan", "WangWu", 500.0);
});
thread1.setName("张三给王五500 x1");
thread2.setName("王五给张三1000");
thread3.setName("张三给王五500 x2");
thread1.start();
thread2.start();
thread3.start();
while (true) { }
}
}

Java锁对象和条件对象的使用的更多相关文章

  1. threading 官方 线程对象和锁对象以及条件对象condition

    官方地址:https://docs.python.org/2/library/threading.html#thread-objects 以下只截取condition部分,其他Lock()以及thre ...

  2. java 多线程(三)条件对象

    转载请注明出处:http://blog.csdn.net/xingjiarong/article/details/47417383 在上一篇博客中,我们学会了用ReentrantLock来控制线程訪问 ...

  3. Java锁机制了解一下

    前言 回顾前面: 多线程三分钟就可以入个门了! Thread源码剖析 多线程基础必要知识点!看了学习多线程事半功倍 只有光头才能变强! 本文章主要讲的是Java多线程加锁机制,有两种: Synchro ...

  4. Java锁Synchronized对象锁和类锁区别

    java的内置锁:每个java对象都可以用做一个实现同步的锁,这些锁成为内置锁.线程进入同步代码块或方法的时候会自动获得该锁,在退出同步代码块或方法时会释放该锁.获得内置锁的唯一途径就是进入这个锁的保 ...

  5. 锁对象-条件对象-synchronized关键字

    1 import java.util.concurrent.locks.Condition; 2 import java.util.concurrent.locks.Lock; 3 import ja ...

  6. Java锁 到底锁的是哪个对象?

    更新:在一次和一位专家的交谈中,他对一下代码能否能够成功同步,给予了否定的答案, 他的理由是”以构造函数的成员变量作为synchronized的锁,在多线程的情况下,每一个线程都持有自己私有变量的锁, ...

  7. Java:使用synchronized和Lock对象获取对象锁

    在并发环境下,解决共享资源冲突问题时,可以考虑使用锁机制. 1.对象的锁 所有对象都自动含有单一的锁. JVM负责跟踪对象被加锁的次数.如果一个对象被解锁,其计数变为0.在任务(线程)第一次给对象加锁 ...

  8. Java虚拟机14:Java对象大小、对象内存布局及锁状态变化

    一个对象占多少字节? 关于对象的大小,对于C/C++来说,都是有sizeof函数可以直接获取的,但是Java似乎没有这样的方法.不过还好,在JDK1.5之后引入了Instrumentation类,这个 ...

  9. Java虚拟机18:Java对象大小、对象内存布局及锁状态变化

    一个对象占多少字节? 关于对象的大小,对于C/C++来说,都是有sizeof函数可以直接获取的,但是Java似乎没有这样的方法.不过还好,在JDK1.5之后引入了Instrumentation类,这个 ...

随机推荐

  1. Pytorch使用tensorboardX网络结构可视化。超详细!!!

    https://www.jianshu.com/p/46eb3004beca 1 引言 我们都知道tensorflow框架可以使用tensorboard这一高级的可视化的工具,为了使用tensorbo ...

  2. 【阿里云新品发布·周刊】第13期:链路追踪 Tracing Analysis 商业化首发

    点击订阅新品发布会! 新产品.新版本.新技术.新功能.价格调整,评论在下方,下期更新!关注更多内容,了解更多 最新发布 链路追踪 Tracing Analysis 商业化首发 2019年6月12日15 ...

  3. 【[Offer收割]编程练习赛9 D】 矩阵填数

    [题目链接]:http://hihocoder.com/problemset/problem/1480 [题意] [题解] 这是一道杨氏矩阵的题; 一个固定形状的杨氏矩阵的种类个数; 等于这个杨氏矩阵 ...

  4. iphone开发中调用系统打电话功能

    iphone开发中调用打电话功能,一般有2种: 1.系统的打电话代码,不返回当前程序: Java代码 [[UIApplication sharedApplication] openURL:[NSURL ...

  5. element表格多选实现单选

    9.element多选表格实现单选 userChoose(selection, row) { console.log(selection,'selection') console.log(row,'r ...

  6. Java Annotation详解(一): 理解和使用Annotation

    JDK1.5之后,引入了元数据的概念,也就是Annotation(注释),其实它是代码里的特殊标记,这些标记可以再编译.类加载.运行时被读取,并执行相应的处理. 元数据的作用: 如果要对于元数据的作用 ...

  7. Python--day69--ORM正反向查找(外键)

    ForeignKey操作 正向查找 对象查找(跨表) 语法: 对象.关联字段.字段   示例: book_obj = models.Book.objects.first() # 第一本书对象 prin ...

  8. zoj 2338 The Towers of Hanoi Revisited

    The Towers of Hanoi Revisited Time Limit: 5 Seconds Memory Limit: 32768 KB Special Judge You all mus ...

  9. .NET 创建 WebService

    服务器端代码 using System; using System.Collections.Generic; using System.Linq; using System.Web; using Sy ...

  10. 2019-10-31-Resharper-去掉注释拼写

    title author date CreateTime categories Resharper 去掉注释拼写 lindexi 2019-10-31 9:8:5 +0800 2018-09-04 1 ...