栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > Java

多线程深化之线程安全

Java 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

多线程深化之线程安全

    我们设想一个这样的场景,有一个水杯,可以加水和喝水,不能边加水边喝水。喝水和加水就相当于两个线程,我们直接看代码。

package gouzaos;

import java.util.ArrayList;
import java.util.List;


public class Str {

    public static void main(String[] args) {
        //杯子
       Cup cup = new Cup();
        //多线程调用这个方法
        new Thread(() -> {
            cup.set();
        }).start();
        new Thread(() -> {
            cup.get();
        }).start();

//        Cup cup01 = new Cup();
//       Cup cup02 = new Cup();
//        多线程调用这个方法--并行执行
//        new Thread(() -> {
//            cup01.set();
//        }).start();
//        new Thread(() -> {
//            cup02.get();
//        }).start();

//        StringBuffer s1 = new StringBuffer();
//        StringBuffer s2 = new StringBuffer();
//        new Thread(() -> {
//            s1.append("a");
//        }).start();
//        new Thread(() -> {
//            s1.append("b");
//        }).start();
//        new Thread(() -> {
//            s2.append("c");
//        }).start();


    }

}


class Cup {

    //创建一个容器
    private List list = new ArrayList<>();

    public synchronized void set() {
        System.out.println("Hello13SynchronizedCpu.set我在向杯子里加水--开始");
        try {
            Thread.sleep(5000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        System.out.println("Hello13SynchronizedCpu.set我在向杯子里加水--结束");
    }

    public synchronized void get() {
        System.out.println("Hello13SynchronizedCpu.get我在喝水--开始");
        try {
            Thread.sleep(5000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        System.out.println("Hello13SynchronizedCpu.get我在喝水--结束");
    }


}

我们看代码的执行结果

 为什么这个时候的线程是安全的呢?大家仔细看一看set get方法前的修饰符,可以理解为正是因为有了synchronized,使得当set方法执行的时候会上锁,或者get方法执行的时候会上锁,防止了刚开始加水,就开始了喝水。保证了线程的安全。大家可以尝试一下,假如把synchronized去掉的话,再执行结果就会发现线程是不安全的。

这里大家要记住两句话,静态方法隶属于类,普通方法隶属于对象。

这里的set方法,get方法都是普通方法,隶属于对象,synchronized锁住的可以是一个对象,也可以是一个数据。那么当我们把注释的第二段代码放开的话,也就是cup01,cup02就会发现,线程是不安全的。因为分别new出了两个对象,相当于在堆里面分别指向了两个新的对象。synchronized就失效了。

最后子月补充一点,StringBufer为什么被称为线程安全的呢?其实大家一看源码就明白了,它的源码的方法上都是有synchronized修饰的。相当于本身就封装了synchronized.大家结合着上面的例子来理解StringBuffer。

我们来看代码中第三部分被注释的地方,s1.append("a")和s1.append("b")就是线程安全的。s1和s2指向了不同的对象,二者之间也是互不干扰的。

如果有什么疑惑,欢迎大家评论区留言哦!(*^▽^*)

转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/298885.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号