Java多线程加锁例子

Java多线程加锁例子


一、错误示例


    static int a = 0; //多线程同时操作 val a

    
    @Test
    public void test4() throws InterruptedException {
        Runnable runnable = () -> {
			while (a < 10) {
				a++;
				System.out.print(a + "\t");
			}
        };
        Thread t1 = new Thread(runnable);
        t1.start();  //线程t1 启动

        Thread t2 = new Thread(runnable);
        t2.start();  //线程t2 启动

        Thread t3 = new Thread(runnable);
        t3.start();  //线程t3 启动

    }

输出结果: 1 3 4 6 7 8 9 10 2 6
原因:
1.代码可见 我用lambda实现了runnable的实现类
2.下面创建了三个线程分别对同一个runnable变量进行start启动,让jvm去跑这个runnable

这时候三个线程是不同的
但是线程里面有个while条件,注意where条件
a如果小于10,就进循环,然后 a++ 了
这时候我说有bug,你听我细细道来,

假如第一个线程t1 第一次进来a是小于10的…因为第一次a=0
然后t1线程还没有执行到a++的时候t2又进来了
…这时候t1能放过t2吗?
t2给t1说:你管得着吗?你又没有关门,凭什么不让我进来,
这时候t1执行了a++, 但是t1还没有执行输出,t2也执行了a++
输出了:1 (反正不知道是哪个线程输出的)
输出了:3 (我估计是t3线程的干扰)

二、正确示例


    static int a = 0; //多线程同时操作 val a
    static final Object obj = new Object(); //锁对象
    
    @Test
    public void test4() throws InterruptedException {
        Runnable runnable = () -> {
            synchronized (obj) {
                while (a < 10) {
                    a++;
                    System.out.print(a + "\t");
                }
            }
        };
        Thread t1 = new Thread(runnable);
        t1.start();  //线程t1 启动

        Thread t2 = new Thread(runnable);
        t2.start();  //线程t2 启动

        Thread t3 = new Thread(runnable);
        t3.start();  //线程t3 启动

    }

输出结果: 1 2 3 4 5 6 7 8 9 10
原因:
static final Object obj = new Object();
synchronized (obj) {

}
每个线程执行到synchronized代码块的时候,都会把同一个变量 锁上
因为是static修饰的,所以多个线程都会同意这个锁是同一个锁
因为每个线程进来之前都会去看看这个锁对象有没有被占用
所以实现了分离

t1进来了,其他都进不去,当t1跑完循环,离开了 t2进来了,但是条件不满足了,a已经不小于10了
所以这个正确的结果是同一个线程完成的

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值