Javase碎碎念之线程的安全性--synchronized 以及其它常用的块

本文通过一个银行取款系统的案例,深入浅出地讲解了线程安全问题及synchronized关键字的应用。展示了如何使用synchronized解决多线程下的资源竞争问题,避免数据不一致。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

线程的安全,在线程的安全性问题中synchronized关键字很重要,本篇文章主要讲解一下synchronized在线程锁中的简单应用.(注意:只有在对数据进行修改,写,线程才会不安全,如果只是对数据的查询,则效率优先,不加synchronized)
先来看下面一段代码

package com.qftest;

/**
 * 在线取钱系统
 * 
 * @author 24526
 *
 */
public class Demo1 {
	public static void main(String[] args) {
		quqian acc = new quqian(10010, "123456", 2000d);
		husband hu = new husband(acc);
		wife wi = new wife(acc);
		new Thread(hu).start();
		new Thread(wi).start();

	}
}

class husband implements Runnable {
	quqian acc;
	husband hu;

	public husband(quqian acc) {
		this.acc = acc;
	}

	@Override
	public void run() {
		this.acc.qu(10010, "123456", 200);

	}

}

class wife implements Runnable {

	quqian acc;
	wife wi;

	public wife(quqian acc) {
		this.acc = acc;
	}

	@Override
	public void run() {
		this.acc.qu(10010, "123456", 4400);

	}
}

class quqian {
	int id;
	String pwd;
	double money;
	double blance;

	public quqian(int id, String pwd, double blance) {
		this.id = id;
		this.pwd = pwd;
		this.blance = blance;

	}

	public void qu(int id, String pwd, double money) {
		if (id == this.id && pwd.equals(this.pwd)) {
			System.out.println("密码输入正确,请稍后...");
			if (blance > money) {
				blance -= money;
				System.out.println("您当前可用余额为:" + blance);
			} else {
				System.out.println("可用余额不足!!");
			}
		} else {
			System.out.println("密码或账号输入错误,请重新输入...");
		}
	}

}

结果为:

密码输入正确,请稍后...
可用余额不足!!
密码输入正确,请稍后...
您当前可用余额为:1800.0

上述代码展示了一个经典的取钱案列,在该代码中出现了线程不安全的情况.
在这种情况下,线程锁synchronized应运而生.
使用方法:
synchronized(临界资源对象){
代码(原子操作)
}
下面是加上了synchronized的代码(部分)



class husband implements Runnable {

quqian acc;

husband hu;



public husband(quqian acc) {

this.acc = acc;

}



@Override

public void run() {

synchronized (acc) {



this.acc.qu(10010, "123456", 8800);

}



}



}



class wife implements Runnable {



quqian acc;

wife wi;



public wife(quqian acc) {

this.acc = acc;

}



@Override

public void run() {

synchronized (acc) {



this.acc.qu(10010, "123456", 400);

}



}

}


结果:

密码输入正确,请稍后...
可用余额不足!!
密码输入正确,请稍后...
您当前可用余额为:1600.0

需要注意的是,在使用synchronized的时候资源一定要锁对,如果直接锁方法的话,很可能直接锁住了整个类的对象,所以建议使用synchronized同步块
synchronized(临界资源对象){
代码(原子操作)
}

来简单介绍一下各种块
1)方法中的块(局部块):用来解决变量的作用域,在该块中定义的变量出了这个块就用不了
2)类中的块:就是在成员属性的位置放置的代码块,称为构造代码块(在方法外部),与构造方法的作用类似(初始化对象信息).如果是static,则叫静态代码块,与方法代码块不同的是,它是随着类的加载而加载,在方法之前加载.
3)同步块,(也是在方法里面),上面讲了,现在来总结一下
a)上面语法中的临界资源对象可以是任何对象,但是一般推荐使用共享资源.
b)同步方法中无需指定同步监视器,因为同步方法中的同步监视器是this即该对象本身,或者class只是类的模子

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

我只会javase

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值