美文网首页一起来学Android吧
笔记 35 | java线程之线程安全与非线程安全

笔记 35 | java线程之线程安全与非线程安全

作者: 项勇 | 来源:发表于2017-11-15 16:09 被阅读19次

地址

CSDN http://blog.csdn.net/xiangyong_1521/article/details/78541142


线程安全与非线程安全

ArrayList和Vector
HashMap和HashTable
StringBuilder和StringBuffer
这些有什么区别?

这些面试题常被问,答案是,左边的都是非线程安全,右边都是线程安全!

然后又问你,什么是线程安全,什么是非线程安全呢?

A.线程安全

当多个线程类并发操作某类的方法A,来修改这个A方法的某个成员变量的值B,B不会出错,则我们就说,该的这个A方法是线程安全的。
  某类的某方法是否线程安全的关键是:
  (1) 该方法是否修改该类的成员变量;
  (2) 是否给该方法加锁(是否用synchronized关键字修饰)。

B.非线程安全

当多个线程类并发操作某类的方法A,来修改这个A方法的某个成员变量的值B,B会出错,则我们就说,该的这个A方法是非线程安全的。


synchronized

如果要把这个方法变成线程安全的,则用 synchronized关键字来修饰该方法即可:

class counnt{
        private int count = 0;
        
        /*
         * 当有多个线程类同时操作这个方法是,就容易出问题
         */
        public void add(){
            count++;
        }
        
        /*
         * 当加了synchronized修饰后,就是线程安全的了,不过性能很低
         */
        public synchronized void adds(){
            count++;
        }
    }

例子理解:

public Double dou(){
        int a = 5;
        int b = 2;
        return new Double(a/b);
    }

在执行这个方法时,每一个线程都有自己的独立的栈区。当线程进入到方法执行断的时候,一个方法变量在方法代码段中被创建,并保存在线程的栈区(静态方法也放在这里)。不同线程执行这段代码时,会有不同的a/b变量。所以这里是线程安全的,因为没有数据共享。

考虑下面的例子,多线程情况下只执行一次并可以重用结果:

private Double dou;
    public Double dou(){
        int a = 5;
        int b = 2;
        if (dou == null) {
            dou = new Double(a/b);
        }
        return dou;
    }

这个地方虽然优化了,但可惜他不是线程安全的。两个线程并发执行的时候同时进入到dou ==null这个位置,这样可能会new出一个脏的数据。

    private static ThreadLocal local = new ThreadLocal();
    public Double dou(){
        int a = 5;
        int b = 2;
        if (local.get() == null) {
            local.set(new Double(a/b));
        }
        return (Double)local.get();
    }

ThreadLocal类封装了任何类型对象,并把它绑定到当前线程。线程执行dou()方法的时候,实例pi返回的是当前线程的对象。这样的调用是线程安全的。

线程安全跟非线程安全如何取舍

从第一个例子可得知,非线程的方法添加synchronized修饰就可以转化为线程安全,但是性能会相差20倍左右,如果不加的话,该类的成员变量又可能发生错误,所以具体就看你的需求,一个是否有很多线程操作这个方法,一个是否注重它的性能!


相关文章

  • 笔记 35 | java线程之线程安全与非线程安全

    地址 CSDN http://blog.csdn.net/xiangyong_1521/article/detai...

  • 2.1synchronized同步方法

    “线程安全”与“非线程安全”相关的技术点,它们是学习多线程技术时一定会遇到的经典问题。“非线程安全”其实会在多个线...

  • 2019-03-07线程安全和非线程安全

    [JAVA中的线程安全与非线程安全] 线程安全就是多线程访问时,采用了加锁机制,当一个线程访问该类的某个数据时,进...

  • Java并发——别再问 ReentrantLock 的原理了

    说到并发,我们会马上想到锁,使用锁来保证各线程之间能够安全访问临界区以及非线程安全的数据。那为啥 Java 要提供...

  • 十、线程安全

      本篇主要侧重原理,与Java语言层面的线程安全手段关系不大。 一、Java语言中的线程安全   这里的讨论的线...

  • JAVA线程安全及性能的优化笔记(五)——ThreadLocal

    前期回顾 JAVA线程安全及性能的优化笔记(四)——什么是线程安全? 一、ThreadLocal原理 1. 线程程...

  • JAVA 线程安全 非线程安全

    前段时间写了一个多线程,具体的功能的就是同一个请求对象去做远程调用获取数据,单线程顺序执行没有任何问题,在多线程状...

  • Kotlin 单例

    1.懒汉模式 java kotlin 2.懒加载(非线程安全) java kotlin 3.懒加载(线程安全) j...

  • 初识Java虚拟机

    1:Java虚拟机内存模型主要分为5大区域,其中共有区域(线程非安全)为:Java堆、方法区,线程私有(线程安全)...

  • 线程不安全?

    1、什么是线程不安全? 线程安全是java学习中的重点,了解哪些情况下线程不安全,可让初学者更好的理解 线...

网友评论

    本文标题:笔记 35 | java线程之线程安全与非线程安全

    本文链接:https://www.haomeiwen.com/subject/nkchvxtx.html