锁对象

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

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. CF1238E.Keyboard Purchase 题解 状压/子集划分DP

    作者:zifeiy 标签:状压DP,子集划分DP 题目链接:https://codeforces.com/contest/1238/problem/E 题目大意: 给你一个长度为 \(n(n \le ...

  2. Top 10 Free IT Certification Training Resources

    1. Cybrary Cybrary takes the open source concept and applies it to IT training. Many of the courses ...

  3. 微信支付、支付宝支付和QQ钱包支付

    最近忙于对接微信支付和支付宝支付,注册微信公众号,认证公众号,注册微信支付商户号并进行认证: 签约支付宝支付产品(手机网站支付.PC网站支付),注册支付宝企业账号(企业账号权限更大): 注册QQ钱包商 ...

  4. shell Usage

    Usage(){ cat <<EOF Usage: $ [tenant] $ (Run database table check_table_data_config all tenants ...

  5. 设置 Tomcat 的JVM运行内存

    win7,64位: Tomcat7.0.5:jdk1.7: 情况一:Tomcat注册成系统服务,如何修改JVM运行内存? WINDOW 64位 , cmd打开注册表(regedit) HKEY_LOC ...

  6. @bzoj - 4382@ [POI2015] Podział naszyjnika

    目录 @description@ @solution@ @accepted code@ @details@ @description@ 长度为 n 的一串项链,每颗珠子是 k 种颜色之一. 第 i 颗 ...

  7. c语言中的字节数关系、

    转载自:传送门 16位编译器 char :1个字节 char*(即指针变量): 2个字节 short int : 2个字节 int:  2个字节 unsigned int : 2个字节 float: ...

  8. POJ 1961 Period 还是next数组的含义、

    题意:求所给串的前缀(包括原串)中有多少循环串(子串长度至少要是周期的两倍) 思路:还是next数组的应用问题.如果不懂next数组的话 http://www.cnblogs.com/sasuke-/ ...

  9. Linux中ifcfg-eth0配置参数说明

    ifcfg-eth0在/etc/sysconfig/network-scripts下, 其配置如下: DEVICE=物理设备名IPADDR=IP地址NETMASK=掩码值NETWORK=网络地址BRO ...

  10. HDU 1071

    题意:就是求给你一个抛物线的三个点,第一个给定的点是抛物线的顶点,让你求直线p2p3与抛物线的定积分 思路:因为题目条件给了顶点,所以直接用抛物线的顶点式去求. 本弱弱数学太差.还得复习一下公式 #i ...