Synchronized使用

一言不合就贴出代码:
以下就是三个线程同时操作一个对象:

public class MyThread2 extends Thread {
    private Personal personal;
    public MyThread2(Personal personal){
        this.personal = personal;
    }
    @Override
    public void run() {
        System.out.println(this.getName()+":"+personal.getName());
        System.out.println(this.getName()+":"+personal.getAge());
        System.out.println(this.getName()+":"+personal.getSex());
    }
}

    public static void main(String[] args){

        Personal personal = new Personal();
        personal.setName("zangsan");
        personal.setAge(11);
        personal.setSex((byte) 1);

        MyThread2 t1 = new MyThread2(personal);
        MyThread2 t2 = new MyThread2(personal);
        MyThread2 t3 = new MyThread2(personal);
        t1.start();
        t2.start();
        t3.start();
    }

运行结果:

Thread-2:zangsan
Thread-0:zangsan
Thread-1:zangsan
Thread-0:11
Thread-2:11
Thread-0:1
Thread-1:11
Thread-2:1
Thread-1:1

从运行结果,感觉还行,没什么问题,但是,真的是这样吗?

public class ThreadLocalDemo {

    public static void main(String[] args){

        Buys buys = new Buys();
        //初始化总现金
        buys.setTotal(100);

        MyThread2 t1 = new MyThread2(buys);
        MyThread2 t2 = new MyThread2(buys);
        MyThread2 t3 = new MyThread2(buys);
        t1.start();
        t2.start();
        t3.start();
    }
}

public class MyThread2 extends Thread {

    private Buys buys;

    public MyThread2(Buys buys){
        this.buys = buys;
    }

    @Override
    public void run() {
        //执行买香烟的业务,一包烟20块钱

        buys.setTotal(buys.getTotal() - 20);
        System.out.println(this.getName()+":剩余现金有"+buys.getTotal());
    }
}

运行结果:

Thread-1:剩余现金有80
Thread-2:剩余现金有60
Thread-0:剩余现金有80

从这个运行结果来看,显然存在很大的问题,三个人(三个线程)用这个100块钱都做一个买烟的业务,剩余的现金应该都是80,60,40才对吧。
这就是所谓的线程不安全。

解决办法是在关键业务上给Buys对象加锁

        //执行买香烟的业务,一包烟20块钱
        synchronized (buys){
            buys.setTotal(buys.getTotal() - 20);
            System.out.println(this.getName()+":剩余现金有"+buys.getTotal());
        }

运行结果是:

Thread-1:剩余现金有80
Thread-2:剩余现金有60
Thread-0:剩余现金有40

好了, 线程安全了。

总结:
(1)Synchronized给对象加锁,使同一时间只能有一个线程操作对象;
(2)只有一个线程执行结束另一个线程才能继续执行业务;
(3)线程虽然安全了,但是并行操作变成了并发操作,速度相对变慢了,在资源竞争比较激烈的情况下,显然Synchronized执行效率很慢(要理解串行、并行、并发的概念)

那么能不能做到既安全又快速的办法呢?这里有介绍Java并发编程:Lock

场景:
当资源竞争比较激烈时,用Lock;反之,用Synchronized。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
【社区内容提示】社区部分内容疑似由AI辅助生成,浏览时请结合常识与多方信息审慎甄别。
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

相关阅读更多精彩内容

友情链接更多精彩内容