非线程安全问题

news2024/11/25 19:33:35

目录

实例变量共享导致的“非线程安全问题”

如何解决这个问题?

i--与System.out.println()出现引起的“非线程安全问题”


非线程安全主要是指多个线程对同一个对象中的同一个实例变量进行操作时会出现值被更改、值不同步的情况,进而影响程序的执行流程。

实例变量共享导致的“非线程安全问题”

首先,自定义线程类中的实例变量针对其他线程可以是共享的,也可以是不共享的。

public class MyThread extends Thread{
    private int count = 5;
    public MyThread(String name){
        super();
        this.setName(name);//设置线程名称
    }
    @Override
   public void run(){
        super.run();
        while (count>0){
            count--;
            System.out.println("由"+this.currentThread().getName()+"计算,count="+count);
        }
   }
}
public class Run {
    public static void main(String[] args) {
        MyThread a = new MyThread("A");
        MyThread b = new MyThread("B");
        MyThread c = new MyThread("C");
        a.start();
        b.start();
        c.start();
    }
}

运行结果:

也就是说,一共创建了3个线程,每个线程有自己的count变量,在执行过程中自己减少自己的count变量的值。这也就表明当前情况是线程不共享的情况

public class MyThread extends Thread{
    private int count = 5;
    @Override
   public void run(){
        super.run();
            count--;
            System.out.println("由"+this.currentThread().getName()+"计算,count="+count);
   }
}
public class Run {
    public static void main(String[] args) {
        MyThread myThread = new MyThread();

        Thread a = new Thread(myThread,"A") ;
        Thread b = new Thread(myThread,"B") ;
        Thread c = new Thread(myThread,"C") ;
        a.start();
        b.start();
        c.start();
    }
}

运行结果:

出现两个3,说明,A和B同时对count进行了处理,产生了“非线程安全”问题。

此时为什么会出现“非线程安全”问题呐?

原因在于:在某些JVM中,count--操作要分解成3步去执行:(1)获取到原有的count值。(2)计算count-1。(3)对count进行重新赋值。在这个过程中可能会被其他线程打断。也就是说,在这三个步骤中,如果有多个线程同时访问,那么很大概率会出现“非线程安全”问题。

i--操作会出现以上的问题,同理i++操作也同样会出现以上的问题。

以上出现非线程安全的情况是多个线程操作同一个对象的同一个实例变量,导致值不准确。

如何解决这个问题?

这个时候我们就需要进行上锁了。

在run方法前加上synchronized关键字,这样可以使多个线程在执行run方法时,“排队”执行。

如果一个线程要执行run方法,首先要判断run方法是否上锁,如果上锁,说明有其他线程在调用run方法,这个线程就要进行等待,等待其他线程将run方法调用结束后,才能继续调用run方法。如果没有上锁,那么直接调用。

当一个线程想要执行同步方法里面的代码,它会首先尝试去拿到这把锁,如果能拿到,那么该线程就会执行同步方法中的代码。如果不能拿到,那么这个线程就会不断的去尝试拿到这把锁,直到它成功拿到了这把锁为止。

i--与System.out.println()出现引起的“非线程安全问题”

public class MyThread extends Thread{
    private int i = 5;

    @Override
    public void run() {
        System.out.println("i="+(i--)+"  threadName="+Thread.currentThread().getName());
    }
}
public class Run {
    public static void main(String[] args) {
        MyThread run = new MyThread();
        Thread t1 = new Thread(run);
        Thread t2 = new Thread(run);
        Thread t3 = new Thread(run);
        Thread t4 = new Thread(run);
        Thread t5 = new Thread(run);


        t1.start();
        t2.start();
        t3.start();
        t4.start();
        t5.start();
    }
}

运行结果:

这里输出了2个5,也就是说,这里也出现了非线程安全问题。

println的源码:

虽然println方法在内部是synchronized同步的,但是i--操作是在进入println之前发生的,所以依旧有可能出现非线程安全问题。

这也就告诉我们:在synchronized之前执行的代码也有可能是不安全的。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/750506.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

科目一速通技巧笔记,简记

常规 累计积分制度(12满)周期12月 虚假材料1年,假1吊二撤三醉五逃终身 假1500 骗三2k以下 初次领证1年实习期、实习标志,18~70岁 拼装车、报废车,吊销 200~2k 没有中心线(一条路)城市道路3…

路径规划算法:基于白鲸优化的路径规划算法- 附代码

路径规划算法:基于白鲸优化的路径规划算法- 附代码 文章目录 路径规划算法:基于白鲸优化的路径规划算法- 附代码1.算法原理1.1 环境设定1.2 约束条件1.3 适应度函数 2.算法结果3.MATLAB代码4.参考文献 摘要:本文主要介绍利用智能优化算法白鲸…

Python、STK、MATLAB的连接和使用

写在前面 预备知识: Python通过命令行调用MATLAB的简单实现。这篇文章讲明了如何使用 Python 调用 MATLAB 的原理和过程,并给出相应代码。 STK、MATLAB、SQL的连接和使用。这篇文章讲明了STK 11.2、MATLAB 2014a、SQL 2019的安装过程,以及…

超越99%的程序员,chatgpt用C++写个线程安全无锁环形队列

​肝了一个周末,我们一起来欣赏chatgpt写的代码吧。让其用C为我们写一个线程安全的环形队列,并逐步提出一些需求。 先看带锁的实现。 带锁版本 我对chatgpt的需求是: 用C实现线程安全的环形队列,提供代码注释,以及g…

Meetup 报名|07.22 StarRocks Friends 与你相约广州

夏日炎炎,经历了杭州和上海两站的成功活动后,社区开发者的热情依旧如火如荼!在更加炽热的七月,我们即将迎来 StarRocks & Friends 的第三站--广州! 社区依旧秉持连接 StarRocks 社区专家与用户共同探讨大数据领域…

MySQL数据库 - 基本数据类型

目录 一、数据类型分类 二、数据类型 1、tinyint 类型 有符号 tinyint 范围测试 无符号 tinyint 范围测试 2、bit 类型 3、float 类型 有符号 float 范围测试 无符号 float 范围测试 4、decimal 类型 5、char 类型 6、varchar 类型 7、日期类型 8、enum类型、set类型…

Codeforces Round 739 (Div. 3)

A.Dislike of Threes AC代码&#xff1a; #include<iostream> #include<algorithm> #include<cstring> using namespace std; const int N2e510; int f[N]; int cnt; int main() {for(int i1;;i){if(i%3!0&&i%10!3) f[cnt]i;if(cnt>1000) break…

第一阶段-第六章 Python的数据容器

目录 一、数据容器入门  1.学习目标  2.为什么要学习数据容器  3.什么是数据容器  4.本小节的总结 二、数据容器&#xff1a;list&#xff08;列表&#xff09;  2.1列表的定义  1.学习目标  2.为什么需要列表  3.列表的定义  4.本节的代码演示  5.本小节的…

【Java练习题汇总】《第一行代码JAVA》面向对象基础篇,汇总Java练习题——面向对象:特性、类与对象、数组、String、内部类... ~

Java练习题 面向对象基础篇 1️⃣ 面向对象基础篇 1️⃣ 面向对象基础篇 一、填空题 面向对象的三大特征&#xff1a;_______ 、_______ 、_______。类由_______和_______组成。运算符_______的作用是根据对象的类型分配内存空间。当对象拥有内存空间时&#xff0c;会自动调…

oceanbase基础

与mysql对比 分布式一致性算法 paxos 存储结构&#xff08;引擎&#xff09;用的是两级的 数据库自动分片功能&#xff0c;提供独立的obproxy路由写入查询等操作到对应的分片 多租户 方便扩展 存储层 http://www.hzhcontrols.com/new-1391864.html LSM tree&#xff0c;is very…

CnOCR 使用教程

目录 一、 简介二、使用教程三、效果展示 一、 简介 CnOCR 是 Python 3 下的文字识别&#xff08;Optical Character Recognition&#xff0c;简称OCR&#xff09;工具包&#xff0c;支持简体中文、繁体中文&#xff08;部分模型&#xff09;、英文和数字的常见字符识别&#…

[COCI2010-2011#6]STEP

目录 1.题目&#xff1a; 题目描述 输入格式 输出格式 2.思路 1.ans数组的维护 2.L and R 的维护 3.ne数组与pr数组的维护 4.len数组&#xff1a; 3.代码&#xff1a; 1.有注释版&#xff1a; 2.copy版&#xff1a; 1.题目&#xff1a; 题目描述 给定一个长度为N的…

Java设计模式-责任链(Chain of Responsibility)模式

介绍 Java责任链&#xff08;Chain of Responsibility&#xff09;设计模式是指很多处理对象构成一个链&#xff0c;链中前一个对象指向后一个对象。请求在链中传递&#xff0c;一个请求可以被一个或者多个对象处理。调用方&#xff08;即客户端&#xff09;不知道请求会被链中…

【UniApp开发小程序】项目创建+整合UI组件(FirstUI和uView)

创建项目 下图为初始化的项目的文件结构 引入组件 俗话说&#xff1a;“工欲善其事&#xff0c;必先利其器”&#xff0c;为了更加方便地开发出页面较为美观的小程序&#xff0c;我们先引入成熟的UI组件&#xff0c;再开始开发之旅。&#xff08;如果你是前端高手&#xff0…

ardupilot IMU陀螺仪方向的重要性

目录 文章目录 目录摘要1.简介---BMI088 方向2.控制摘要 本节主要记录IMU陀螺仪方向的重要性,欢迎批评指正!!! 1.简介—BMI088 方向 注意这个BMI088 的IMU方向,特别是是那个左上角的黑色点点,他的坐标系满足右手坐标系,但是我们无人机坐标系是北东地坐标系,因此需要把…

Cobalt Strike实战实例

客户端 初始化界面如下&#xff1a; 可以多个客户端同时连接&#xff0c;可以聊天。 msg 指定id 文字。 msg 文字。 创建监听器 这里出现了&#xff0c;监听设置不成功。原因是服务端的CS4.0报错了。我重新下载就可以了。如果这里有问题&#xff0c;可联系我。我帮你。这里解…

python+requests接口自动化测试

原来的web页面功能测试转变成接口测试&#xff0c;之前大多都是手工进行&#xff0c;利用postman和jmeter进行的接口测试&#xff0c;后来&#xff0c;组内有人讲原先web自动化的测试框架移驾成接口的自动化框架&#xff0c;使用的是java语言&#xff0c;但对于一个学java&…

Feign远程调用组件

Feign Feign是Netfix开发的一个轻量级REstFul的HTTP服务客户端,是以java接口注解的方式调用HTTP请求,而不用像java中通过封装HTTP请求报文的方式直接调用,可以帮助我们更加便捷,优雅的调用HTTP API Feign RestTemplate Ribbon Hystrix 本质:封装了HTTP调用流…

JAVA (static) 简述

前言&#xff1a; 在力扣上提交代码&#xff0c;发现用static定义变量&#xff0c;和不用static修饰变量&#xff0c;虽然每次运行的结果都一样&#xff0c;但是提交的结果却有通过与不通过两种情况。 测试题目&#xff1a;组合&#xff08;力扣&#xff09;dfs 回溯 剪枝 JA…

Redis数据结构 — List

目录 链表结构设计 ​编辑链表节点结构设计 链表的优势与缺陷 Redis 的 List 对象的底层实现之一就是链表。C 语言本身没有链表这个数据结构的&#xff0c;所以 Redis 自己设计了一个链表数据结构。 链表结构设计 typedef struct list {//链表头节点listNode *head;//链表尾…