锁对象

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

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. Mac OSX原生读写NTFS功能开启方法

    macOX系统内建的NTFS支持默认只能读不能写 原生读写NTFS,需要自行终端命令手动开启 1. 插上磁盘 此时Mac桌面应该会显示出插入的磁盘,但是当你想把文件拖入磁盘的时候,发现是不能拖进去的, ...

  2. golang micro client 报错500 {"id":"go.micro.client","code":408,"detail":"call timeout: context deadline exceeded","status":"Request Timeout"}

    go micro web端连接services时,第一次访问提示500(broken pipe),排查发现客户端请求services时返回 {"id":"go.micro ...

  3. 2018-2-13-WPF-获得触笔悬停元素上

    title author date CreateTime categories WPF 获得触笔悬停元素上 lindexi 2018-2-13 17:23:3 +0800 2018-2-13 17:2 ...

  4. part11-LED驱动程序设计-part11.1-字符设备控制

  5. @topcoder - SRM611D1L3@ ElephantDrinking

    目录 @description@ @solution@ @accepted code@ @details@ @description@ 给定有一个 n*n 的平原,其中一些格子有些泉水.泉水每单位时间 ...

  6. cf1234-div3

    A 水题 B 直接看2,发现`unordered_map被卡了...` 乖乖离散化 C 有六种水管,可以任意的旋转,使得有一条从(1, 0)到(2, n)的通路. 找规律,当时写D没来得及看 #inc ...

  7. pytorch之expand,gather,squeeze,sum,contiguous,softmax,max,argmax

    目录 gather squeeze expand sum contiguous softmax max argmax gather torch.gather(input,dim,index,out=N ...

  8. 高可用之keepalived的配置文件详解

    ! Configuration File for keepalived global_defs { notification_email { acassen@firewall.loc failover ...

  9. requires php ~7.1 -> your PHP version (7.0.18) does not satisfy that requirement

    一个大兄弟本地用了 PHP 7.1 进行开发,而我本地是 PHP 7.0, 于是悲剧发生了. composer install 之后报错 Loading composer repositories w ...

  10. ASP.NET MVC4.0+EF+LINQ+bui+bootstrap+网站+角色权限管理系统(2)

    创建公共分页参数类Common/GridPager.cs using System; using System.Collections.Generic; using System.Linq; usin ...