JavaEE初阶(4)——线程安全

硬件电路(22)-TTL和232切换电路 工作中会遇到TTL和232电平的通信的状态,为了实现一种便捷的切换方式,参考了一些文章,提供一种电路方便大家使用。 阅读详情

本文旨在 总结线程安全问题的原因和解决方案

多线程带来的风险——线程安全

线程是并发执行 调度是随机的

1序言——实例

1.1.start 和join

我们可以通过start()方法启动线程 再使用 join() 方法使得对应线程 先执行完毕

T1 T2线程谁先join 谁后join无所谓

(1) t1先结束 t2后结束:

main在t1.join阻塞等待  t1结束         main 在t2.join阻塞等待  t2结束

main继续执行后续打印——最终结果,打印的值,是t1 t2都执行完的值

(2) t2先结束 t1后结束:

main在t1.join阻塞        等 t2结束         t1.join继续阻塞    t1结束  t1.join继续执行

main执行到  t2.join (由于t2 已经结束 此处是t2.join是不会阻塞的)       

main继续执行后续打印——最终结果,打印的值,还是t1 t2都执行完的值

以上两者 总的阻塞时间都一样       区别在于是 两个join各自阻塞一会 还是在一个join全都阻塞完

1.2.原子操作

以 count++ 为例 

看起来是一行代码 但是站在CPU的视角 是三条指令

1.load 把内存中的值 (count变量)读取到cpu寄存器

2.add 把指定寄存器的值,进行+1操作(结果还是在这个寄存器里)

3.save 把寄存器中的值 写回到内存中

CPU执行这三条指令的过程中,随时可能触发线程的调度切换

2线程安全问题 产生的根本原因

2.1五个常见原因

1.【根本】操作系统对线程的调度 是随机的——抢先式执行

2.多个线程同时修改同一个变量

3.修改操作,不是原子的

4.内存可见性问题,引起的线程不安全

5.指令重排序 引起的线程不安全

2.2如何解决线程安全问题

1.【根本】操作系统对线程的调度 是随机的——抢先式执行

——操作系统的底层设定,普通程序员无法左右

2.多个线程同时修改同一个变量

——调整代码结构,规避一些线程不安全的代码(此方案不够通用)

3.修改操作,不是原子的

——Java中解决线程安全问题 最主要的方案—— 加锁

通过加锁操作,把非原子操作 打包成原子操作

把锁 “锁上” 称为“加锁”

把锁 “解开”称为“解锁”

一旦把锁加上,其他人想要加锁,只能进行阻塞等待

针对于上文 实例2 就可以使用锁 把非原子操作 count++ 包裹起来

在count++之前 加锁  计算结束后,再解锁

3.加锁操作 Synchronized

3.1常规写法

加锁前 需要定义锁对象       一般常用Object 类型

基本用法如下

为了解决线程安全问题——两个线程,针对同一个对象加锁,才会产生互斥效果

(一个线程上锁,另一个就要阻塞等待,等到第一个i线程释放,才有机会)

如果是不同的锁对象,此时不会有互斥效果,线程安全问题,没有得到改变

synchronized(locker){        XXXX        }

其中 {   表示加锁         } 表示释放锁

3.2变种写法

可以使用synchronized 修饰方法

用synchronized修饰代码块

可变形为:

使用synchronized修饰普通方法 相当于 给this加锁

此外如果

使用synchronized修饰静态方法,相当于给 类对象 加锁

4.可重入

4.1由来

实际开发中很容易 写出两次一样的加锁

内层产生阻塞等待,等到前一次加锁被释放,第二次加锁的阻塞才会接触(继续执行)

1.第一次加锁可以成功(锁没有人用)

2.第二次进行加锁 会触发阻塞等待 因为锁对象已经被占用

为了解决上述问题 Java中synchronized就引入可重入

4.2具体实现

当某个线程针对一个锁,加锁成功后

后续该线程再次针对这个锁进行加锁——不会触发阻塞,而是继续往下执行

因为当前这把锁被这个线程持有——但如果是其他线程尝试加锁,就会正常阻塞

可重入锁的实现原理——关键在于让锁对象,内部保存,当前是哪个线程持有的这把锁

后续有线程针对 这个锁加锁的时候,对比一下,锁持有者的线程和请求者的线程是否相同

同理 可以引入一个变量 计数器(0)

每次触发 {  计数器++   每次触发 }  计数器--

当计数器--为0时,就是真正需要解锁的时候

5.死锁

一个线程 一把锁 连续加锁两次

两个线程 两把锁 每个线程获得一把锁之后,尝试获取对方的锁

N个线程 M把锁——哲学家就餐问题

5.1死锁的构成

1.锁是互斥的,一个线程拿到锁之后,另一个线程再尝试获得锁,必须要阻塞等待

2.锁是不可抢占的(不可剥夺) t1拿到锁后,t2想获得此锁,只能阻塞等待,不可抢占

3.请求和保持  一个线程拿到锁1之后,不释放锁1的前提下,获取锁2

——把嵌套的锁改成并列的锁

4.循环等待 多把锁互相等待形成循环(A等B B等C  C等A)

——约定好加锁顺序就可以破除等待循坏

5.2小结

6.内存可见性

6.1具体表现

——构成线程安全问题的原因之一

T1线程负责读取  T2线程负责修改

虽然输入非0值        但此时t1线程循环没有结束

故这是一个BUG——修改线程修改的值,没有被读取线程成功读到——”内存可见性问题“

原因:在多线程程序中,编译器的判断会出现失误,导致逻辑出错

6.2 Volatile——解决内存可见性问题

在语法中 引入volatile关键字 修饰某个变量

此时编译器对这个变量的读取操作,不会被优化成寄存器

t2修改了 t1能及时看见

7.Wait / Notify

7.1 基本含义

等待/通知 ——用于协调线程之间的执行逻辑的顺序

可以让后执行的逻辑,等待先执行的逻辑 先跑

虽然无法直接干预 调度器的调度顺序

但是可以让后执行的逻辑(线程)等待,等待到 先执行的逻辑跑完了

通知当前的线程,让他继续执行

7.1 join和wait的区别

join 是等另一个线程彻底执行完,才继续走

wait 等待另一个线程执行 notify 唤醒 ,才继续走(并不需要另一个线程执行完)

锁的等待是不受控制的

当多个线程竞争一把锁的时候

获取到锁的线程如果释放了,接下来是哪个线程获得锁? ——不确定(随机调度)

操作系统的调度是随机的

其他线程都属于在锁上阻塞等待,是阻塞状态

当前这个释放锁的线程,是就绪状态——很有可能再次拿到这个锁

例子: 把CPU视为鸟妈妈  每个线程视为鸟宝宝

        资源分配不合理 容易造成线程饥饿 甚至线程饿死

当拿到锁的线程,发现要执行的任务,时机还不成熟,就用wait阻塞等待

wait 和notify 是Object的方法——Java中的任意对象都提供了 wait 和notify方法

7.3锁的释放时机

wait 关键在于——要先释放锁,给其他线程获得锁的机会

要先上锁,才谈释放

同理 要先拿到锁 再唤醒线程

务必确保 先wait 后notify 才有作用

如果先notify 后wait ,此时wait无法被唤醒

notify这个线程没有副作用 (不报错)

8.wait 和 sleep区别

wait 和join类型 ——同样提供“死等” “限时等待”版本

wait有等待时间        sleep也有等待时间

wait可以使用notify提前唤醒        sleep也可以用Interrupt提前唤醒

最主要的区别在于——对锁的操作

  1. wait 必须要搭配锁 ,先加锁  再使用 wait        sleep不需要
  2. 如果都是在 synchronized 内部使用,wait会释放锁 sleep不会释放锁

抱着锁 睡         其他线程无法获取这个锁

《QGIS快速入门与应用基础》239:指北针样式选择(预设/自定义) 系统解析指北针设计的核心规范与实操方法。文章首先强调行业规范红线,包括强制要求N字标注、箭头辨识度等关键要素,通过正误示例对比强化合规意识。其次详细讲解QGIS内置预设样式的分类应用,提供极简箭头、标准三角箭头等4类样式的选型对照表,并配图说明适用场景。最后介绍从基础微调到SVG导入的进阶自定义方法,帮助用户实现从合规到专业的样式设计。全文贯穿"合规优先、可读为本、美观为辅"原则,配有详细操作截图与规范对照表,适合从GIS新手到专业制图人员参考。 阅读详情

相关推荐

哨兵1号(Sentinel-1)雷达SAR数据预处理全流程:从下载到精确配准

本文详细介绍了哨兵1号(Sentinel-1)雷达SAR数据从下载到精确配准的全流程预处理方法。内容涵盖SLC与GRD数据选择、ASF平台下载技巧,并重点解析了使用SNAP软件进行几何校正、辐射定标及高精度配准的核心步骤,为InSAR形变监测等应用提供可靠的数据基础。

weixin_29208327的博客 478

JavaEE初阶——多线程(4)线程安全

本文介绍了Java多线程中的volatile关键字以及wait/notify机制。volatile通过内存屏障保证内存可见性和有序性,但不保证原子性;通过MESI协议和缓存同步机制确保线程能感知变量修改。wait/notify用于线程间协调,必须在synchronized代码块中使用,wait使线程等待并释放锁,notify唤醒等待线程。notifyAll可唤醒所有等待线程。这些机制解决了线程间的内存可见性问题和执行顺序协调问题,是Java多线程编程的重要工具。

Yoko_999的博客 790

第3章 信息技术服务(一)

对 第三章 《信息技术服务》中第一、二、三节 <内涵与外延、原理与组成、服务生命周期>进行总结、归纳

好好学习,天天向上的博客 733

JavaEE 初阶(6)——多线程4之线程状态+线程安全上

本篇讲解了线程状态,介绍了部分与线程安全相关的问题,包括线程不安全的原因,解决线程不安全的方法——使用关键字synchronized

2301_80243321的博客 1144

Mac和VScode配置fortran

macOS系统 vscode fortran gfortran 终端

weixin_43047707的博客 2410

基于PID的定速巡航控制系统设计【MATLAB源码+Word文档】

本文详细介绍了定速巡航控制是一种车辆驾驶辅助系统,它能让驾驶者在高速或长途驾驶时,设定一个固定的车速,然后车辆会自动维持这个速度行驶,无需驾驶者持续踩油门。这大大减轻了驾驶者的疲劳,同时也提高了行驶的安全性。PID定速巡航控制系统是一种利用比例(Proportional)、积分(Integral)和微分(Derivative)控制算法来实现车辆定速巡航的先进系统。这种系统能够根据设定的速度,自动调整油门开度或制动力度,使车辆保持恒定的速度行驶。这种控制系统具有响应速度快、控制精度高、稳定性好等优点。

weixin_761237174的博客 1669

JavaEE初阶——多线程4(线程安全 和 解决办法(synchronized))

类对象中,是对这个类的各种信息的描述(类名,包含哪些属性,每个属性的名字,有啥参数,参数是啥类型/public/private…但是,并非是加锁之后,执行三个操作的过程中,线程就不调度了(仍然是是随机调度,随时可能会从CPU上下来) ~ ~上述代码中,两个线程中都是用到了t实例调用加锁的方法,锁中用到锁对象,其中的this,都是指的t这个实例,所以是同一个对象,所以会存在锁竞争!而count++,包含多个CPU指令,一个线程执行这些指令,执行到一半,可能会被调度走,从而给其他线程“可乘之机”。

2401_88679387的博客 1528

基于小波变换的信号降噪处理及仿真研究_信号处理方法推荐--1(转载自用,侵删)...

综述作者:aresmiki链接:https://www.zhihu.com/question/23701194/answer/167005497来源:知乎著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。非平稳信号处理应该是现在信号处理技术最新的也是最热的研究方向了,信号处理方法从最早的时域统计到傅里叶变换的频域分析,是人们认识信号本质的一次巨大飞跃,给了分析人员换个角度看世界的...

weixin_32144483的博客 1249

JavaEE初阶(4)(线程的状态、线程安全、synchronized、volatile、wait 和 notify、多线程的代码案例:单例模式——饿汉懒汉、阻塞队列)

线程的状态、线程安全、产生线程安全的原因、解决线程安全{ synchronized关键字、synchronized关键字用的锁存在Java对象头里、synchronized 的重要特性——可重入【死锁(Deadlock)、解决死锁】、 volatile 关键字、wait 和 notify 【 wait( ) 方法、notify()方法、notifyAll()方法】}、多线程的代码案例{单例模式【饿汉模式、懒汉模式、懒汉模式-多线程版】、阻塞队列【解耦合、削峰填谷、了解标准库的阻塞队列、自己实现阻塞队列】}

m0_74343467的博客 553

ANSYS workbench (关于normal stiffness factor接触刚度因子)

关于normal stiffness factor接触刚度因子的含义和设置方法

weixin_43730845的博客 6804

基于STM32L4XX、HAL库的MCP4561数字电位器驱动程序设计

/ HAL库需要左移一位。* @param address: 设备地址(0x2C-0x2F)* @param hmcp: MCP4561句柄。* @param hmcp: MCP4561句柄。* @param hmcp: MCP4561句柄。* @param hmcp: MCP4561句柄。* @param hmcp: MCP4561句柄。* @param hmcp: MCP4561句柄。* @param hmcp: MCP4561句柄。* @param hi2c: I2C句柄。

zhusl6688的博客 340

【JavaEE 初阶(二)】线程安全问题

本篇文章主要介绍了sychronized加锁操作,死锁的成因,死锁的解决,内存可见性问题以及内存可见的解决方案,最后介绍了wait和notify的运用。

weixin_69049913的博客 2350

人工智能训练师三级考试备考全攻略|报名条件+真题+补贴申领一站式通关(2026版)

本专栏是人工智能训练师三级考证最完整的备考指南,共77篇文章,覆盖从职业认知、报名实操、AI基础知识、数据标注、模型训练测试部署、考前冲刺到考后进阶的全链路。本导读按模块整理了全部文章链接,帮你快速定位所需内容。人工智能训练师是国家认定的正式职业,证书可在osta.mohrss.gov.cn查询,三级证书可申领最高3120元技能补贴。

白话机器学习 1794

【JavaEE 初阶】线程安全核心知识点总结

听到线程安全问题,大家是不是心里在想知道何为线程安全、为什么会产生线程安全问题。那是由于多线程并发时,共享资源的非原子操作易引发数据错乱,线程安全问题暗藏风险。所以理解其根源与解决之道,是保障程序稳定的关键。接下来我将一一叙述线程安全问题。

2301_80350265学无止尽5的博客 1641

IEM模型,地表粗糙度模拟

利用微波反演土壤水分时候,利用IEM模型可以实现对随机地表的模拟

深度学习工具包 DeepLearningToolbox

深度学习工具包Deprecation notice.-----This toolbox is outdated and no longer maintained.There are much better tools available for deep learning than this toolbox, e.g. [Theano](http://deeplearning.net/software/theano/), [torch](http://torch.ch/) or [tensorflow](http://www.tensorflow.org/)I would suggest you use one of the tools mentioned above rather than use this toolbox.Best, Rasmus.DeepLearnToolbox================A Matlab toolbox for Deep Learning.Deep Learning is a new subfield of machine learning that focuses on learning deep hierarchical models of data.It is inspired by the human brain's apparent deep (layered, hierarchical) architecture.A good overview of the theory of Deep Learning theory is[Learning Deep Architectures for AI](http://www.iro.umontreal.ca/~bengioy/papers/ftml_book.pdf)For a more informal introduction, see the following videos by Geoffrey Hinton and Andrew Ng.* [The Next Generation of Neural Networks](http://www.youtube.com/watch?v=AyzOUbkUf3M) (Hinton, 2007)* [Recent Developments in Deep Learning](http://www.youtube.com/watch?v=VdIURAu1-aU) (Hinton, 2010)* [Unsupervised Feature Learning and Deep Learning](http://www.youtube.com/watch?v=ZmNOAtZIgIk) (Ng, 2011)If you use this toolbox in your research please cite [Prediction as a candidate for learning deep hierarchical models of data](http://www2.imm.dtu.dk/pubdb/views/publication_details.php?id=6284)```@MASTERSTHESIS\{IMM2012-06284, author = "R. B. Palm", title = "Prediction as a candidate for learning deep hierarchical models of data", year = "2012",}```Contact: rasmusbergpalm at gmail dot comDirectories included in the toolbox-----------------------------------`NN/` - A library for Feedforward Backpropagation Neural Networks`CNN/` - A library for Convolutional Neural Networks`DBN/` - A library for Deep Belief Networks`SAE/` - A library for Stacked Auto-Encoders`CAE/` - A library for Convolutional Auto-Encoders`util/` - Utility functions used by the libraries`data/` - Data used by the examples`tests/` - unit tests to verify toolbox is workingFor references on each library check REFS.mdSetup-----1. Download.2. addpath(genpath('DeepLearnToolbox'));Example: Deep Belief Network---------------------```matlabfunction test_example_DBNload mnist_uint8;train_x = double(train_x) / 255;test_x = double(test_x) / 255;train_y = double(train_y);test_y = double(test_y);%% ex1 train a 100 hidden unit RBM and visualize its weightsrand('state',0)dbn.sizes = [100];opts.numepochs = 1;opts.batchsize = 100;opts.momentum = 0;opts.alpha = 1;dbn = dbnsetup(dbn, train_x, opts);dbn = dbntrain(dbn, train_x, opts);figure; visualize(dbn.rbm{1}.W'); % Visualize the RBM weights%% ex2 train a 100-100 hidden unit DBN and use its weights to initialize a NNrand('state',0)%train dbndbn.sizes = [100 100];opts.numepochs = 1;opts.batchsize = 100;opts.momentum = 0;opts.alpha = 1;dbn = dbnsetup(dbn, train_x, opts);dbn = dbntrain(dbn, train_x, opts);%unfold dbn to nnnn = dbnunfoldtonn(dbn, 10);nn.activation_function = 'sigm';%train nnopts.numepochs = 1;opts.batchsize = 100;nn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.10, 'Too big error');```Example: Stacked Auto-Encoders---------------------```matlabfunction test_example_SAEload mnist_uint8;train_x = double(train_x)/255;test_x = double(test_x)/255;train_y = double(train_y);test_y = double(test_y);%% ex1 train a 100 hidden unit SDAE and use it to initialize a FFNN% Setup and train a stacked denoising autoencoder (SDAE)rand('state',0)sae = saesetup([784 100]);sae.ae{1}.activation_function = 'sigm';sae.ae{1}.learningRate = 1;sae.ae{1}.inputZeroMaskedFraction = 0.5;opts.numepochs = 1;opts.batchsize = 100;sae = saetrain(sae, train_x, opts);visualize(sae.ae{1}.W{1}(:,2:end)')% Use the SDAE to initialize a FFNNnn = nnsetup([784 100 10]);nn.activation_function = 'sigm';nn.learningRate = 1;nn.W{1} = sae.ae{1}.W{1};% Train the FFNNopts.numepochs = 1;opts.batchsize = 100;nn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.16, 'Too big error');```Example: Convolutional Neural Nets---------------------```matlabfunction test_example_CNNload mnist_uint8;train_x = double(reshape(train_x',28,28,60000))/255;test_x = double(reshape(test_x',28,28,10000))/255;train_y = double(train_y');test_y = double(test_y');%% ex1 Train a 6c-2s-12c-2s Convolutional neural network %will run 1 epoch in about 200 second and get around 11% error. %With 100 epochs you'll get around 1.2% errorrand('state',0)cnn.layers = { struct('type', 'i') %input layer struct('type', 'c', 'outputmaps', 6, 'kernelsize', 5) %convolution layer struct('type', 's', 'scale', 2) %sub sampling layer struct('type', 'c', 'outputmaps', 12, 'kernelsize', 5) %convolution layer struct('type', 's', 'scale', 2) %subsampling layer};cnn = cnnsetup(cnn, train_x, train_y);opts.alpha = 1;opts.batchsize = 50;opts.numepochs = 1;cnn = cnntrain(cnn, train_x, train_y, opts);[er, bad] = cnntest(cnn, test_x, test_y);%plot mean squared errorfigure; plot(cnn.rL);assert(er<0.12, 'Too big error');```Example: Neural Networks---------------------```matlabfunction test_example_NNload mnist_uint8;train_x = double(train_x) / 255;test_x = double(test_x) / 255;train_y = double(train_y);test_y = double(test_y);% normalize[train_x, mu, sigma] = zscore(train_x);test_x = normalize(test_x, mu, sigma);%% ex1 vanilla neural netrand('state',0)nn = nnsetup([784 100 10]);opts.numepochs = 1; % Number of full sweeps through dataopts.batchsize = 100; % Take a mean gradient step over this many samples[nn, L] = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.08, 'Too big error');%% ex2 neural net with L2 weight decayrand('state',0)nn = nnsetup([784 100 10]);nn.weightPenaltyL2 = 1e-4; % L2 weight decayopts.numepochs = 1; % Number of full sweeps through dataopts.batchsize = 100; % Take a mean gradient step over this many samplesnn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.1, 'Too big error');%% ex3 neural net with dropoutrand('state',0)nn = nnsetup([784 100 10]);nn.dropoutFraction = 0.5; % Dropout fraction opts.numepochs = 1; % Number of full sweeps through dataopts.batchsize = 100; % Take a mean gradient step over this many samplesnn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.1, 'Too big error');%% ex4 neural net with sigmoid activation functionrand('state',0)nn = nnsetup([784 100 10]);nn.activation_function = 'sigm'; % Sigmoid activation functionnn.learningRate = 1; % Sigm require a lower learning rateopts.numepochs = 1; % Number of full sweeps through dataopts.batchsize = 100; % Take a mean gradient step over this many samplesnn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.1, 'Too big error');%% ex5 plotting functionalityrand('state',0)nn = nnsetup([784 20 10]);opts.numepochs = 5; % Number of full sweeps through datann.output = 'softmax'; % use softmax outputopts.batchsize = 1000; % Take a mean gradient step over this many samplesopts.plot = 1; % enable plottingnn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.1, 'Too big error');%% ex6 neural net with sigmoid activation and plotting of validation and training error% split training data into training and validation datavx = train_x(1:10000,:);tx = train_x(10001:end,:);vy = train_y(1:10000,:);ty = train_y(10001:end,:);rand('state',0)nn = nnsetup([784 20 10]); nn.output = 'softmax'; % use softmax outputopts.numepochs = 5; % Number of full sweeps through dataopts.batchsize = 1000; % Take a mean gradient step over this many samplesopts.plot = 1; % enable plottingnn = nntrain(nn, tx, ty, opts, vx, vy); % nntrain takes validation set as last two arguments (optionally)[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.1, 'Too big error');```[![Bitdeli Badge](https://d2weczhvl823v0.cloudfront.net/rasmusbergpalm/deeplearntoolbox/trend.png)](https://bitdeli.com/free "Bitdeli Badge")

【JavaEE初阶】多线程初阶下部

这篇博客博主开始讲述多线程的下部,上部在博主的上一篇博客,需要的柚柚们可以看看~([链接在这里点击即可])

2301_80085602的博客 1616

VC中sqlite的使用

在VC中对sqlite的使用,实现数据库大批数据的快速插入,读取数据库中的数据在ListCtrl中显示

JavaEE初阶——线程安全

在Java中,线程安全是十分重要的。因为我们要让代码编写出来后锁产生的结果与我们的想法是一致的。所以本篇文章就为大家讲解一下线程安全的相关内容。

m0_74815183的博客 1422

【JavaEE】线程安全的集合类

线程安全的集合类~~~

做梦都想要三十万年薪~ 1537

【后端开发】JavaEE初阶—线程安全问题与加锁原理(超详解)

本期总结了关于多线程编程的重要问题,线程状态,以及线程安全问题讲解,并且如何解决线程安全问题,进行了原理讲解,并提出加锁的概念和实现;还附上了代码加以讲解

GGBond778的博客 1844

【JavaEE初阶 — 多线程】线程安全问题 & synchronized

【JavaEE初阶 — 多线程】线程安全问题 & Synchronized 观察线程安全问题,分析了造成线程安全问题造成的三个原因:线程的随机调度,多个线程修改共享数据(修改同一个变量),以及原子性问题,并讲述了如何解决这三种原因引发的线程不安全;并讲述了 synchronized 互斥 和 可重入 的特性,并给出了 synchronized的使用案例;简单介绍了Java标准库中的线程安全类和线程不安全类。

OuO-1 的博客 1282

javaEE初阶————多线程初阶(2)

今天给大家带来第二期啦,保证给大家讲懂嗷;

2301_79083481的博客 1635

【JavaEE初阶】线程安全问题及解决方法

线程安全的概念 想给出⼀个线程安全的确切定义是复杂的,但我们可以这样认为: 如果多线程环境下代码运行的结果是符合我们预期的,即在单线程环境应该的结果,则说这个程序是线程安全的。 线程安全,在单线程环境下和多线程环境下都不会出现问题。

m0_61876562的博客 1642

【JavaEE】线程安全

Java线程安全,以及关键字synchronized,volatile,死锁的三种情况以及造成死锁的三种原因

2303_77535762的博客 1903

JavaEE 线程安全

什么是线程安全问题?很直观的说,就是一段代码,在单线程的环境下没有问题,但是在多线程的环境下却出现了问题,我们则可称这段代码存在线程安全问题

Mwt258的博客 1473

javaEE初阶————多线程初阶(4)

这又是什么新的神奇玩意呢,我们先不谈单例模式,先来谈谈设计模式,什么是设计模式呢,我们只需要用设计模式就好了,而大佬们考虑的就多了,这些设计模式就像棋谱,只要按照棋谱来下,你的水平就不会太差,设计模式就是大佬们给我们小卡拉米设计的计算机棋谱,而单例模式就是其中之一,还有很多的设计模式;那么什么是单例模式呢?单例模式就是保证某个类在程序中只存在一份示例这是为什么,就像DataSource,我们用数据库的时候有一份就好了,假设这个类实例化一次的开销就是几百个g,这样的开销可承担不起;

2301_79083481的博客 2631

【JavaEE初阶】深入解析单例模式中的饿汉模式,懒汉模式的实现以及线程安全问题

本期讲解了关于设计模式之单例模式中的两个重要模式,即饿汉模式和懒汉模式,关于他们的实现代码,也进行了编写;以及最重要的两个模式的线程安全问题,小编进行了注重分析问题的产生,以及如何解决都有涉及~~~

GGBond778的博客 3008

JavaEE 第4节 线程安全问题

刚才讲解线程安全问题的原因时,我们提到了原子性、修改同一个变量这两个关键字,这里所说的锁实际上就是。

HYY的博客 939

JavaEE初阶——线程安全(多线程)

介绍了,java中多线程安全,为什么会出现多线程安全,使用synchronized锁让其一些操作变成原子性,从而解决部分多线程问题,volatile关键字解决内存可见性和指令从排序问题,使用wait和notity确保线程执行顺序

2401_89019969的博客 964
上一篇: JavaEE初阶 进程 && 线程(3)
下一篇: JavaEE初阶(5)——单例模式
FrantF
博客等级 码龄3年 5粉丝 15原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值