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内存模型.它们的答案是一致的:能够让我们更好的 ...
随机推荐
- mybatis多参数查询
第三种比较好点 http://www.2cto.com/database/201409/338155.html
- [Android Pro] Android中全局Application的onCreate多次调用问题
一般来说Application的onCreate方法只会执行一次, 如果应用中采用多进程方式,oncreate方法会执行多次,根据不同的进程名字进行不同的初始化, 就是在application中多添加 ...
- Unity5.1 新的网络引擎UNET(九) UNET 官方推荐视频教程
孙广东 2015.7.14 在新的网络引擎出现之前,Unity提供的是 内置 Raknet网络引擎, 这一次Unity想更新UGUI一样,花了大的手笔更新了, UNET. 原来的旧的网络组件 被提示 ...
- Spark1.0.0 history server 配置
在执行Spark应用程序的时候,driver会提供一个webUI给出应用程序的执行信息.可是该webUI随着应用程序的完毕而关闭port,也就是说,Spark应用程序执行完后,将无法查看应用程序的历史 ...
- IOS 开发学习33 使用sqlite3
sqlite3 命令行简单使用 sqlite3 路径 //打开数据库路径连接 select * from sqlite_master where type="table"; //显 ...
- COSMOSBOX手遊制作手册(Word备份)
20140712版 版本号 Version 日期 Date 作者 Author 变更主要原因描述 Brief Description 1.0 2014-4-26 陈霈霖 初稿 2.0 1. 前言 本手 ...
- Protocol Informatics (PI项目)【基于网络轨迹的协议逆向工程文献学习】
Protocol Informatics[基于网络轨迹的协议逆向工程文献学习]by tsy 声明: 1)本报告由博客园bitpeach撰写,版权所有,免费转载,请注明出处,并请勿作商业用途.恕作者著作 ...
- 在Docker里使用(支持镜像继承的)supervisor管理进程(转)
这篇文章是受 dockboard 之托帮忙翻译的与 docker 有关的技术文章.译自 Using Supervisor with Docker to manage processes (suppor ...
- java分页功能代码
import java.util.ArrayList; import java.util.List; /** * * @author cheney * * @date Aug 31, 2012 */ ...
- SSH面试题目
一简答 spring工作原理 为什么要用spring 3.请你谈谈SSH整合 4.介绍一下Spring的事务管理 5.Struct2基本流程 6.在Hibernate应用中Java对象的状态有哪些? ...