Java语言】【Java基础】线程安全问题及产生的原因是什么?

2020-10-22 10:22发布

6条回答
那些年很冒险的梦。
2楼 · 2020-10-27 14:36

其实就一句话:只要是有多个线程访问并修改某个变量或是区域的话,一定要加1653上同步设置(比如同步控制语句,互斥锁,信号量,原子操作等等)。

B/S结构中,如果你不编写类似Apache等的HTTP Server,那么你不用考虑线程安全这个问题。

如果有多个用户访问数据库的情况出现:

1.若数据库中间件封装了同步功能,则不需要考虑线程安全;

2.若数据库本身支持并发操作,则不需要考虑线程安全;

3.否则则需要考虑线程安全的问题。


小猪仔
3楼 · 2020-10-22 14:26

线程安全问题产生的原因:

1,多个线程在操作共享的数据;

2,操作共享数据的线程代码有多条;

当一个线程在执行操作共享数据的多条代码过程中,其他线程参与了运算,就会导致线程安全问题的产生。

解决思路:

就是将多条操作共享数据的线程代码封装起来,当有线程在执行这些代码的时候,其他线程是不可以参与运算的。

必需要当前线程把这些带那都执行完毕后,其他线程才能参与运算。


aijingda
4楼 · 2020-10-22 14:33

    最近工作中遇到不少多线程问题,但自己一直对多线程的理解比较表层。没有深入探究。正是最近工作中遇到的问题,致使我深入的去了解多线程安全问题为什么会产生。

    多线程使我们的计算机可以同时运行多个程序,感觉很美好。

    but,多线程的安全问题,到底怎么回事,到底怎么来的,对于有点理想主义的我来说这简直就是BUG。

    网上有不少介绍多线程产生的原因的。我大致看了一遍,感觉都介绍的太粗线条,可能不太适合经验不足者理解。

    so,我就自己整理一下我自己的理解。如有谬误欢迎大家指正和交流。

    首先java 虚拟机中 内存区域分为线程共享和线程私有的两大类。

    

现场 画图哈哈。

 java虚拟机在执行字节码指令的时候是什么情况呢?

假设int 类型数据a在线程共享区域目前值为0,java执行以下代码时,需要经过哪些操作呢?

public class Test001{ public  int a = 0; public void dosomething(){  a ++ ; }}

我写了一个java类,编译一下


执行命令javap -l -v Test001.class

我得到了如下结果


这个是主要执行自增的字节码指令,我们来看下执行过程;

0:将对象本身入栈,这里隐含第一个参数为this;

1:复制栈顶元素,也就是对象的引用;

2:获取栈顶对象属性a的值,并将其入栈;

5:将int型1推送至栈顶;

6:将栈顶两个int类型数据相加,并将结果入栈;

7:将栈顶的值放入对象属性a中;

10:return,不用解释了

我们可以看到简单的一个自增操作,虚拟机要执行的指令却不止一个。

在这一组指令执行过程中,cpu是有可能切换线程的,如果在当前线程t1被挂起之后其他线程修改了这个对象的a属性值,那么恢复线程执行时t1线程将会覆盖其他线程已经修改过的值。


所以,,线程安全问题就是这么产生的了。

理解了怎么产生的就更容易解决如何避免线程安全问题了。


霸气的名字 - 喜欢晴天
5楼 · 2020-10-22 18:28

线程安全问题出现的根本原因:
    1. 必须要存在两个或者两个以上的线程共享着一个资源。
    2. 操作共享资源的代码必须有两句或者两句以上。



    1. 同步代码块
        synchronized(锁){
            需要被同步的代码
        }
               
    2. 同步函数。   
        修饰符 synchronized 返回值类型   函数名(形参列表..){

        }
    注意:
        1. 同步代码块的锁可以是任意的对象。 同步函数的锁是固定 的,非静态函数的锁对象是this对象。 静态函数的锁对象是class对象。
        2. 锁对象必须是多线程共享的对象,否则锁不住。
        3. 在同步代码块或者是同步函数中调用sleep方法是不会释放锁对象的,如果是调用了wait方法是会释放锁对象的。


樱田妮妮NiNi
6楼 · 2020-10-23 09:37

线程安全问题:

线程安全出现的根本原因:

 1.存在两个或者两个以上的线程对象共享同一个资源;

  2.多线程操作共享资源代码有多个语句。

线程安全问题的解决方案(2个):

方式一:同步代码块

方式二:同步函数(同步函数就是使用synchronized修饰一个函数)

皮卡皮卡-李
7楼 · 2020-10-28 20:30

其实就一句话:只要是有多个线程访问并修改某个变量或是区域的话,一定要加1653上同步设置(比如同步控制语句,互斥锁,信号量,原子操作等等)。

B/S结构中,如果你不编写类似Apache等的HTTP Server,那么你不用考虑线程安全这个问题。

如果有多个用户访问数据库的情况出现:

1.若数据库中间件封装了同步功能,则不需要考虑线程安全;

2.若数据库本身支持并发操作,则不需要考虑线程安全;

3.否则则需要考虑线程安全的问题。


相关问题推荐

  • 回答 7
    已采纳

    里氏代换原则(Liskov Substitution Principle, LSP):所有引用基类(父类)的地方必须能透明地使用其子类的对象里氏代换原则告诉我们,在软件中将一个基类对象替换成它的子类对象,程序将不会产生任何错误和异常,反过来则不成立,如果一个软件实体使用的是一...

  • 回答 8
    已采纳

    心里有个预期,然后看看是以什么目的进这家企业工作,要是赚钱的话,那就多要点,要是学习的话,可以根据情况要一个能养活自己的价格。

  • 回答 4
    已采纳

    Java中有八种数据类型,基础数据类型分别是:byte,short,int,long,float,double,char,boolean,引用数据类型分别是:数组,类和接口。方法传参的时候我们有两种,一种是形式参数(定义方法时写的参数),一种是实际参数(调用方法时给的具体值)。首先...

  • 回答 15
    已采纳

    现在的架构很多,各种各样的,如高并发架构、异地多活架构、容器化架构、微服务架构、高可用架构、弹性化架构等,还有和这些架构相关的管理型的技术方法,如 DevOps、应用监控、自动化运维、SOA 服务治理、去 IOE 等等,还有很多。分布式架构其实就是分布式系...

  • 回答 10

    1、监控GC的状态使用各种JVM工具,查看当前日志,分析JVM参数的设置,分析堆内存快照和GC日志,根据实际的各区域的内存划分和GC的执行时间,判断是否需要进行优化2、分析结果、判断是否需要优化如果各项参数设置合理,系统没有超时的日志出现,GC频率也不高,...

  • 回答 6

    MyBatis 每次创建结果对象的新实例时,它都会使用一个对象工厂(ObjectFactory)实例来完成。 默认的对象工厂需要做的仅仅是实例化目标类,要么通过默认构造方法,要么在参数映射存在的时候通过参数构造方法来实例化。 如果想覆盖对象工厂的默认行为,则可以...

  • 回答 6

    学vue应该要先学习javascript 的基础知识和用法。

  • 回答 8

    1、lambda是jdk8的新特性2、使用lambda的前提,必须是一个接口,接口只能有一个抽象方法3、Lambda 表达式的简单例子:// 1. 不需要参数,返回值为 5  () -> 5    // 2. 接收一个参数(数字类型),返回其2倍的值  x -> 2 * x    // 3. 接受2个参数(数...

  • 回答 4

    1、面向对象编程(OOP):OOP最重要的思想是类,类是模板,从类中构造一个对象,即创建了这个类的一个实例;2、封装:是把数据和行为结合在一起,并对对象使用者隐藏数据的实现过程,通常一个对象中的数据叫他的实例字段(instance field) ;3、继承:Java中允许在已...

  • 回答 6

    jdk1.8的新特性包括如下:一、接口的默认方法与静态方法,也就是接口中可以有实现方法二、Lambda 表达式三、函数式接口与静态导入四、Lambda 作用域在lambda表达式中访问外层作用域和老版本的匿名对象中的方式很相似。你可以直接访问标记了final的外层局部变...

  • 回答 6

    用static修饰,能节省一些内在空间,虽然很有限

  • 回答 6

    这个是在内存中存放的地址,你必须str1.equals(str2)才可以判断的。你可以输出地址看看,你这样比较的是两个地址,当然是false了。第一个直接缓存 数据共享Hello,是true。

  • 回答 3

    采用接口(Interface)的中变量默认为static final的特性在普通类中使用final修饰变量采用了Java 5.0中引入的Enum类型。,也就是所谓的枚举类

  • 回答 8

    同步方法  使用synchronized 修饰方法  ==》 解决线程安全问题同步代码块  synchronized(被加锁的对象){ 代码 }  ==》 解决线程安全问题锁机制Lock  ==》 解决线程安全问题   (这个例子在ex2上修改而成的)...

  • 回答 4

    当多个线程访问同一个共享数据时,有可能会出现线程安全问题

没有解决我的问题,去提问