java 对象 互斥锁_Java多线程中的对象互斥锁

1、为什么会有锁?

在看线程同步的问题之前,我们先看一个生活中的小例子:

我拿着银行卡去ATM取钱,假如我的卡里有3000块,我要取走2000,这个时候,ATM会去银行的数据库里查询我的账户是否有2000以上的余额,如果有,就会让我取走,不幸的是,这个时候,我女朋友也来银行取钱,只不过她在前台取钱,她直接取走了3000,这个时候我的卡里已经没钱了,而我也肯定也不能取出2000了。

我们可以这样想,上面例子中的我和女朋友是两个线程,我们在访问同一块资源,也就是一个账户,这个情况下,是不允许在一个线程访问的时候,另一个线程来打断的,就像我在取钱的时候,我女朋友是不能取的,不能打断我。

我们先来看一段代码:

public class TestThread01 implements Runnable{

Timer timer = new Timer();

public static void main(String[] args) {

TestThread01 t = new TestThread01();

Thread t1 = new Thread(t);

Thread t2 = new Thread(t);

t1.setName("t1");

t2.setName("t2");

t1.start();

t2.start();

}

public void run(){

timer.add(Thread.currentThread().getName());

}

}

class Timer{

private static int num = 0;

public static void add(String name){

num++;

try {

Thread.sleep(1);

} catch (InterruptedException e) {

}

System.out.println(name +":你是第"+num+"使用timer的线程");

}

}

上面的代码我们就能看出两个线程去访问同一个资源,也就是timer的add方法,看一下运行结果:

t1:你是第2使用timer的线程

t2:你是第2使用timer的线程

结果为什么是这样呢?

我们分析一下:

t1启动,访问add方法,num++变为1,这时,t1睡眠,t2启动,t2访问add,num是1,++之后变为2,t2睡眠,t1再继续访问,打印“t1:你是第2使用timer的线程”,然后t1结束,t2继续打印“t2:你是第2使用timer的线程”。

我们这就见到了线程的打断,有的人可能会说是因为sleep了一毫秒,所以才会这样,其实不然,如果没有sleep,也有可能会被打断,也有可能会正确执行。

2、对象互斥锁的用法?

解决方法01:给可能竞争的资源对象加上互斥锁,synchronized (this),锁定当前对象。

class Timer{

private static int num = 0;

public void add(String name){

synchronized (this) {

num++;

try {

Thread.sleep(1);

} catch (InterruptedException e) {

}

System.out.println(name +":你是第"+num+"使用timer的线程");

}

}

}

这时的执行结果:

t1:你是第1使用timer的线程

t2:你是第2使用timer的线程

解决方法02:给竞争的方法加上锁

class Timer{

private static int num = 0;

public synchronized void add(String name){

num++;

try {

Thread.sleep(1);

} catch (InterruptedException e) {

}

System.out.println(name +":你是第"+num+"使用timer的线程");

}

}

结果也是对的。

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值