线程同步 synchronized 同步代码块 同步方法 同步锁
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();
}
}
结果:
线程同步 synchronized 同步代码块 同步方法 同步锁的更多相关文章
- JAVA之旅(十三)——线程的安全性,synchronized关键字,多线程同步代码块,同步函数,同步函数的锁是this
JAVA之旅(十三)--线程的安全性,synchronized关键字,多线程同步代码块,同步函数,同步函数的锁是this 我们继续上个篇幅接着讲线程的知识点 一.线程的安全性 当我们开启四个窗口(线程 ...
- About 静态代码块,普通代码块,同步代码块,构造代码块和构造函数的纳闷
构造函数用于给对象进行初始化,是给与之对应的对象进行初始化,它具有针对性,函数中的一种.特点:1:该函数的名称和所在类的名称相同.2:不需要定义返回值类型.3:该函数没有具体的返回值.记住:所有对象创 ...
- 线程的同步机制:同步代码块&同步方法
解决存在的线程安全问题:打印车票时出现重票,错票 使用同步代码块的解决方案 TestWindow2 package com.aff.thread; /* 使用实现Runnable接口的方式,售票 存在 ...
- java的同步方法和同步代码块,对象锁,类锁区别
/** * @author admin * @date 2018/1/12 9:48 * 作用在同一个实例对象上讨论 * synchronized同步方法的测试 * 两个线程,一个线程调用synchr ...
- 深入理解Java中的同步静态方法和synchronized(class)代码块的类锁
一.回顾学习内容 在前面几篇博客中我我们已经理解了synchronized对象锁.对象锁的重入.synchronized方法块.synchronized非本对象的代码块, 链接:https://www ...
- 2.2.9静态同步synchronized方法与synchronized(class)代码块
关键字synchronized还可以应用在static静态方法上,这样写那是对当前的*.java文件对应的class类进行持锁, 测试如下 package com.cky.bean; /** * Cr ...
- 牛客网Java刷题知识点之什么是代码块、普通代码块、静态代码块、同步代码块、构造代码块以及执行顺序
不多说,直接上干货! 这种形式的程序段我们将其称之为代码块,所谓代码块就是用大括号({})将多行代码封装在一起,形成一个独立的数据体,用于实现特定的算法.一般来说代码块是不能单独运行的,它必须要有运行 ...
- JAVA_四大代码块_普通代码块、构造代码块、静态代码块、同步代码块。
普通代码块 在方法或语句中出现的{}里面的内容就被称为普通代码块,普通代码块和一般的语句执行顺序一样,由他们在代码中出现的次序决定,即--"先出现先执行". 但是不同的普通代码块即 ...
- 静态同步synchronized方法和synchronized(class)代码块
关键字synchronized还可以应用在static静态方法上,如果这样写,那是对当前的*.java文件对应的Class类进行持锁. package synStaticMethod; /** * C ...
随机推荐
- PL/SQL学习(一)
原文参考:http://plsql-tutorial.com/ 组成: 声明部分(可选) 执行部分(必选) 异常处理(可选) 声明: DECLARE 执行: ...
- Swift(三.函数)
一.swift中的函数分为以下几类吧 1>无参无返 2>无参有返 3>有参无返 4>有参有返 5>有参多返 二.看下面几个例子吧 1>无参无返 func a ...
- 如何在django的filter中传递字符串变量作为查询条件(动态改变查询条件)
一般来说在需要查询数据的时候都是以下形式 ret=Articles.objects.filter(id=1) 然而如果要动态的改变查询的条件怎么办呢? 如下代码 def getModelResult( ...
- WARNING L15: MULTIPLE CALL TO SEGMENT
原网页:http://www.cnblogs.com/CuriosityWzk/archive/2011/12/25/2301090.html WARNING L15: MULTIPLE CALL T ...
- POJ 2442 Sequence 优先队列
题目: http://poj.org/problem?id=2442 #include <stdio.h> #include <string.h> #include <q ...
- C语言程序设计做题笔记之C语言基础知识(下)
C 语言是一种功能强大.简洁的计算机语言,通过它可以编写程序,指挥计算机完成指定的任务.我们可以利用C语言创建程序(即一组指令),并让计算机依指令行 事.并且C是相当灵活的,用于执行计算机程序能完成的 ...
- 在mesos上安装storm,并且执行wordcount测试程序
mesos上安装storm 1.基本说明 如果只用一句话来描述storm的话,可能会是这样:分布式实时计算系统.按照storm作者的说法,storm对于实时计算的意义类似于hadoop对于批处理的意义 ...
- 【Ecmall】ECMall2.x模板制作入门系列(认识ECMall模板)
ECMall2.x模板制作入门系列之1(认识ECMall模板) 从ECMall2.0全新架构发布以来,随着版本的不断更新,ECMall已经逐渐走向一个稳定时期,是时候整理一些实用教程了.下面给大家带来 ...
- PHP 切割字符串 点号 不用双斜杠
$name = "tupian.png"; $nameArr = explode(".", $name); 习惯了Java的程序员容易写成 $nameArr = ...
- 【HDU 1542】Atlantis 矩形面积并(线段树,扫描法)
[题目] Atlantis Problem Description There are several ancient Greek texts that contain descriptions of ...