Java同步锁全息详解

public class Account {
private String accountNo;
private double balance;
public Account(String accountNo,double balance){
this.accountNo=accountNo;
this.balance=balance;
}
public double getBalance() {
return balance;
}
public void setBalance(double balance) {
this.balance = balance;
}
public String getAccountNo() {
return accountNo;
}
public void setAccountNo(String accountNo) {
this.accountNo = accountNo;
}
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
Account account = (Account) o;
return accountNo.equals(account.accountNo);
}
@Override
public int hashCode() {
return accountNo.hashCode();
}
}


public class DrawThread extends Thread {
private Account account;
private double drawAmount;
public DrawThread(String name, Account account, double drawAmount) {
super(name);
this.account = account;
this.drawAmount = drawAmount;
}
public void run(){
synchronized (account){
if(account.getBalance()>=drawAmount){
System.out.println(getName() + "取钱成功,吐出钞票: " + drawAmount);
try{
Thread.sleep(1);
}catch(InterruptedException ex){
ex.getStackTrace();
}
account.setBalance(account.getBalance()-drawAmount);
System.out.println("\t余额为:"+account.getBalance());
}else{
System.out.println(getName()+"取钱失败,余额不足");
}
}
}
}


public class DrawTest {
public static void main(String[] args){
Account acct=new Account("1234567",1000);
new DrawThread("甲",acct,800).start();
new DrawThread("乙",acct,800).start();
}
}


public class DrawThread extends Thread {
private Account account;
private double drawAmount;
public DrawThread(String name, Account account, double drawAmount) {
super(name);
this.account = account;
this.drawAmount = drawAmount;
}
public void run(){
// synchronized (account){
if(account.getBalance()>=drawAmount){
System.out.println(getName() + "取钱成功,吐出钞票: " + drawAmount);
try{
Thread.sleep(1);
}catch(InterruptedException ex){
ex.getStackTrace();
}
account.setBalance(account.getBalance()-drawAmount);
System.out.println("\t余额为:"+account.getBalance());
}else{
System.out.println(getName()+"取钱失败,余额不足");
}
// }
}
}

会出现这些情况的结果:

public class Account {
private String accountNo;
private double balance;
public Account(String accountNo,double balance){
this.accountNo=accountNo;
this.balance=balance;
}
//因为账户余额不可以随便更改,所以只为balance提供getter方法
public double getBalance() {
return balance;
}
public String getAccountNo() {
return accountNo;
}
public void setAccountNo(String accountNo) {
this.accountNo = accountNo;
}
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
Account account = (Account) o;
return accountNo.equals(account.accountNo);
}
@Override
public int hashCode() {
return accountNo.hashCode();
}
//提供一个线程安全的draw()方法来完成取钱操作
public synchronized void draw(double drawAmount){
if(balance>=drawAmount){
System.out.println(Thread.currentThread().getName()+"取钱成功!吐出钞票:"+drawAmount);
try{
Thread.sleep(1);
}catch (InterruptedException ex){
ex.printStackTrace();
}
balance-=drawAmount;
System.out.println("\t余额为:"+balance);
}else{
System.out.println(Thread.currentThread().getName()+"取钱失败,余额不足");
}
}
}


public class DrawThread extends Thread {
private Account account;
private double drawAmount;
public DrawThread(String name, Account account, double drawAmount) {
super(name);
this.account = account;
this.drawAmount = drawAmount;
}
public void run(){
account.draw(drawAmount);
}
}


public class DrawTest {
public static void main(String[] args){
Account acct=new Account("1234567",1000);
new DrawThread("甲",acct,800).start();
new DrawThread("乙",acct,800).start();
}
}


class X{
//定义锁对象
private final ReentrantLock lock=new ReentrantLock();
//定义需要保证线程安全的方法
public void m(){
//加锁
lock.lock();
try{
//...method body
}
//使用finally块来保证释放锁
finally{
lock.unlock();
}
}
}


public class Account {
private final ReentrantLock lock=new ReentrantLock();
private String accountNo;
private double balance;
public Account(String accountNo,double balance){
this.accountNo=accountNo;
this.balance=balance;
}
//因为账户余额不可以随便更改,所以只为balance提供getter方法
public double getBalance() {
return balance;
}
public String getAccountNo() {
return accountNo;
}
public void setAccountNo(String accountNo) {
this.accountNo = accountNo;
}
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
Account account = (Account) o;
return accountNo.equals(account.accountNo);
}
@Override
public int hashCode() {
return accountNo.hashCode();
}
//提供一个线程安全的draw()方法来完成取钱操作
public void draw(double drawAmount){
//加锁
lock.lock();
try {
if (balance >= drawAmount) {
System.out.println(Thread.currentThread().getName() + "取钱成功!吐出钞票:" + drawAmount);
try {
Thread.sleep(1);
} catch (InterruptedException ex) {
ex.printStackTrace();
}
balance -= drawAmount;
System.out.println("\t余额为:" + balance);
} else {
System.out.println(Thread.currentThread().getName() + "取钱失败,余额不足");
}
}finally {
lock.unlock();
}
}
}


class A{
public synchronized void foo(B b){
System.out.println("当前线程名为:"+Thread.currentThread().getName()+"进入了A实例的foo()方法");
try{
Thread.sleep(200);
}catch(InterruptedException ex){
ex.printStackTrace();
}
System.out.println("当前线程名为:"+Thread.currentThread().getName()+"试图调用B实例的last()方法");
b.last();
}
public synchronized void last(){
System.out.println("进入了A类的last()方法内部");
}
}
class B{
public synchronized void bar(A a){
System.out.println("当前线程名为:"+Thread.currentThread().getName()+"进入了B实例的bar()方法");
try{
Thread.sleep(200);
}catch(InterruptedException ex){
ex.printStackTrace();
}
System.out.println("当前线程名为:"+Thread.currentThread().getName()+"试图调用A实例的last()方法");
a.last();
}
public synchronized void last(){
System.out.println("进入了B类的last()方法内部");
}
}
public class DeadLock implements Runnable{
A a =new A();
B b=new B();
public void init(){
Thread.currentThread().setName("主线程");
a.foo(b);
System.out.println("进入了主线程之后...");
}
public void run(){
Thread.currentThread().setName("副线程");
b.bar(a);
System.out.println("进入了副线程之后...");
}
public static void main(String[] args){
DeadLock d1=new DeadLock();
new Thread(d1).start();
d1.init();
}
}

结果:
Java同步锁全息详解的更多相关文章
- Java中String做为synchronized同步锁使用详解
Java中使用String作同步锁 在Java中String是一种特殊的类型存在,在jdk中String在创建后是共享常量池的,即使在jdk1.8之后实现有所不同,但是功能还是差不多的. 借助这个特点 ...
- Java分布式锁实现详解
在进行大型网站技术架构设计以及业务实现的过程中,多少都会遇到需要使用分布式锁的情况.那么问题也就接踵而至,哪种分布式锁更适合我们的项目? 下面就这个问题,我做了一些分析: 分布式锁现状: 目前几乎很多 ...
- “全栈2019”Java多线程第十六章:同步synchronized关键字详解
难度 初级 学习时间 10分钟 适合人群 零基础 开发语言 Java 开发环境 JDK v11 IntelliJ IDEA v2018.3 文章原文链接 "全栈2019"Java多 ...
- Java精通并发-自旋对于synchronized关键字的底层意义与价值分析以及互斥锁属性详解与Monitor对象特性解说【纯理论】
自旋对于synchronized关键字的底层意义与价值分析: 对于synchronized关键字的底层意义和价值分析,下面用纯理论的方式来对它进行阐述,自旋这个概念就会应运而生,还是很重要的,下面阐述 ...
- 《手把手教你》系列技巧篇(七十一)-java+ selenium自动化测试-自定义类解决元素同步问题(详解教程)
1.简介 前面宏哥介绍了几种关于时间等待的方法,也提到了,在实际自动化测试脚本开发过程,百分之90的报错是和元素因为时间不同步而发生报错.本文介绍如何新建一个自定义的类库来解决这个元素同步问题.这样, ...
- java.lang.Thread类详解
java.lang.Thread类详解 一.前言 位于java.lang包下的Thread类是非常重要的线程类,它实现了Runnable接口,今天我们来学习一下Thread类,在学习Thread类之前 ...
- Java并发关键字Volatile 详解
Java并发关键字Volatile 详解 问题引出: 1.Volatile是什么? 2.Volatile有哪些特性? 3.Volatile每个特性的底层实现原理是什么? 相关内容补充: 缓存一致性协议 ...
- java之StringBuffer类详解
StringBuffer 线程安全的可变字符序列. StringBuffer源码分析(JDK1.6): public final class StringBuffer extends Abstract ...
- Java内存模型(JMM)详解
在Java JVM系列文章中有朋友问为什么要JVM,Java虚拟机不是已经帮我们处理好了么?同样,学习Java内存模型也有同样的问题,为什么要学习Java内存模型.它们的答案是一致的:能够让我们更好的 ...
随机推荐
- mysql中数据导出成excel文件语句
代码如下 复制代码 mysql>select * from xi_table into outfile ’d:test.xls’; 导出为txt文件: 代码如下 复制代码 select * f ...
- 【实践】用 js 封装java shuffle函数(打乱数组下标方法)
此方法返回的会是一个全新的数组 所以并不会像java里的shuffle函数一样返回一个引用一样的数组 思路如下: 1.新建一个函数传入需要打乱下标的数组 2.获取数组的长度 3.新建一个用来保存并且返 ...
- 【ACM】Crixalis's Equipment
#include "stdio.h" #include "stdlib.h" /* 贪心算法: Ai->x 表示第i个物品的体积 Ai->y 表 ...
- 轻量级的前端UI开发框架 - UIkit
来源:GBin1.com UIkit是YOOtheme团队开发的开源的前端UI界面框架,可以帮助你快速的开发和创建前端UI界面. 基于下列开源项目: LESS jQuery normalize.css ...
- 关于Objective-c和Java下DES加密保持一致的方式
转载自:http://www.cnblogs.com/janken/archive/2012/04/05/2432930.html 最近做了一个移动项目,是有服务器和客户端类型的项目,客户端是要登录才 ...
- vue 仿ele 开发流程
技术栈: vue2 vuex vue-router axios webpack eslint better-scroll 1.安装插件 npm install vue-resource babel-r ...
- OpenERP(odoo)开发实例之搜索检索过去3个月的数据
转自:http://www.chinamaker.net/ OpenERP(odoo)开发实例之搜索过滤:检索过去3个月的数据 解决这个问题的重点在于 relativedelta 的应用 示例代码如下 ...
- Patterns-Flyweight
最近在组里讨论设计模式,第一个是享元模式. 自己贴了一篇这个文章:http://www.cnblogs.com/rush/archive/2011/10/01/2197785.html 感觉这篇讲的不 ...
- phpMyAdmim和Yii 连接Mysql报错。
故障: 之前phpMyAdmim和Yii连接Mysql都好着的.某天,同一时候出现例如以下报错: 1.linux下phpMyAdmin 出现 "缺少 mysqli 扩展,请检查 PHP 配置 ...
- hp-ux 集群,内存 小记
-----查看hp 集群状态信息 # cmviewcl -v CLUSTER STATUS dbsvr up NODE ...