Java多线程并发编程 并发三大要素
发布时间 - 2026-01-11 01:14:27 点击率:次一、原子性

原子,一个不可再被分割的颗粒。原子性,指的是一个或多个不能再被分割的操作。
int i = 1; // 原子操作
i++; // 非原子操作,从主内存读取 i 到线程工作内存,进行 +1,再把 i 写到朱内存。
虽然读取和写入都是原子操作,但合起来就不属于原子操作,我们又叫这种为“复合操作”。
我们可以用synchronized 或 Lock 来把这个复合操作“变成”原子操作。
例子:
private synchronized void increase(){
i++;
}
或
private int i = 0;
Lock mLock = new ReentrantLock();
private void increase() {
mLock.lock();
try {
i++;
} finally{
mLock.unlock();
}
}
这样我们就可以把这个一个方法看做一个整体,一个不可分割的整体。
除此之前,我们还可以用java.util.concurrent.atomic里的原子变量类,可以确保所有对计数器状态访问的操作都是原子的。
例子:
AtomicInteger mAtomicInteger = new AtomicInteger(0);
private void increase(){
mAtomicInteger.incrementAndGet();
}
二、可见性
当多线程访问某一个(同一个)变量时,其中一条线程对此变量作出修改,其他线程可以立刻读取到最新修改后的变量。
int i = 0;
// 线程 1 执行
i++;
// 线程 2 执行
System.out.print("i=" + i);
即使是在执行完线程里的 i++ 后再执行线程 2,线程 2 的输入结果也会有 2 个种情况,一个是 0 和 1。
因为 i++ 在线程 1(CPU1)中做完了运算,并没有立刻更新到主内存当中,而线程 2(CPU2)就去主内存当中读取并打印,此时打印的就是 0。
synchronized和Lock能够保证可见性。
另外volatile关键字也可以解决这个问题(下一篇会讲到)。
三、有序性
我们都知道处理器为了拥有更好的运算效率,会自动优化、排序执行我们写的代码,但会确保执行结果不变。
例子:
int a = 0; // 语句 1 int b = 0; // 语句 2 i++; // 语句 3 b++; // 语句 4
这一段代码的执行顺序很有可能不是按上面的 1、2、3、4 来依次执行,因为 1 和 2 没有数据依赖,3 和 4 没有数据依赖, 2、1、4、3 这样来执行可以吗?完全没问题,处理器会自动帮我们排序。
在单线程看来并没有什么问题,但在多线程则很容易出现问题。
再来个例子:
// 线程 1
init();
inited = true;
// 线程 2
while(inited){
work();
}
init(); 与 inited = true; 并没有数据的依赖,在单线程看来,如果把两句的代码调换好像也不会出现问题。
但此时处于一个多线程的环境,而处理器真的把这两句代码重新排序,那问题就出现了,若线程 1 先执行 inited = true; 此时,init() 并没有执行,线程 2 就已经开始调用 work() 方法,此时很可能造成一些奔溃或其他 BUG 的出现。
synchronized和Lock能确保原子性,能让多线程执行代码的时候依次按顺序执行,自然就具有有序性。
而volatile关键字也可以解决这个问题,volatile 关键字可以保证有序性,让处理器不会把这行代码进行优化排序。
# Java多线程
# 并发编程
# Java并发编程示例(一):线程的创建和执行
# Java并发编程示例(六):等待线程执行终止
# Java并发编程之显示锁ReentrantLock和ReadWriteLock读写锁
# Java并发编程之栅栏(CyclicBarrier)实例介绍
# Java并发编程示例(二):获取和设置线程信息
# Java并发编程示例(七):守护线程的创建和运行
# Java并发编程示例(十):线程组
# Java并发编程总结——慎用CAS详解
# 理解Java多线程之并发编程
# 多线程
# 都是
# 可以用
# 两句
# 解决这个问题
# 单线程
# 是在
# 见性
# 会有
# 多个
# 就不
# 但在
# 很容易
# 能让
# 再来
# 很可能
# 或其他
# 就去
# 已经开始
# 写到
相关栏目:
【
网站优化151355 】
【
网络推广146373 】
【
网络技术251813 】
【
AI营销90571 】
相关推荐:
怎么制作网站设计模板图片,有电商商品详情页面的免费模板素材网站推荐吗?
如何打造高效商业网站?建站目的决定转化率
Laravel如何使用Livewire构建动态组件?(入门代码)
Android中AutoCompleteTextView自动提示
在线制作视频的网站有哪些,电脑如何制作视频短片?
javascript中对象的定义、使用以及对象和原型链操作小结
如何在万网利用已有域名快速建站?
Win11怎么设置默认图片查看器_Windows11照片应用关联设置
Laravel如何使用Socialite实现第三方登录?(微信/GitHub示例)
北京网站制作公司哪家好一点,北京租房网站有哪些?
Win11怎么设置虚拟桌面 Win11新建多桌面切换操作【技巧】
如何在浏览器中启用Flash_2025年继续使用Flash Player的方法【过时】
JavaScript如何实现继承_有哪些常用方法
如何在建站之星网店版论坛获取技术支持?
如何为不同团队 ID 动态生成多个独立按钮
Laravel怎么实现一对多关联查询_Laravel Eloquent模型关系定义与预加载【实战】
网站制作怎么样才能赚钱,用自己的电脑做服务器架设网站有什么利弊,能赚钱吗?
Android仿QQ列表左滑删除操作
Linux系统命令中screen命令详解
Laravel如何使用Blade模板引擎?(完整语法和示例)
Laravel怎么做缓存_Laravel Cache系统提升应用速度的策略与技巧
如何在自有机房高效搭建专业网站?
php嵌入式断网后怎么恢复_php检测网络重连并恢复硬件控制【操作】
如何在云指建站中生成FTP站点?
python中快速进行多个字符替换的方法小结
HTML5空格在Angular项目里怎么处理_Angular中空格的渲染问题【详解】
Laravel怎么使用Blade模板引擎_Laravel模板继承与Component组件复用【手册】
Laravel用户密码怎么加密_Laravel Hash门面使用教程
Laravel路由怎么定义_Laravel核心路由系统完全入门指南
进行网站优化必须要坚持的四大原则
Laravel如何获取当前用户信息_Laravel Auth门面获取用户ID
如何基于云服务器快速搭建个人网站?
深圳防火门网站制作公司,深圳中天明防火门怎么编码?
微信小程序 input输入框控件详解及实例(多种示例)
Laravel如何发送邮件_Laravel Mailables构建与发送邮件的简明教程
详解免费开源的DotNet二维码操作组件ThoughtWorks.QRCode(.NET组件介绍之四)
焦点电影公司作品,电影焦点结局是什么?
JavaScript如何实现类型判断_typeof和instanceof有什么区别
Laravel如何使用Guzzle调用外部接口_Laravel发起HTTP请求与JSON数据解析【详解】
儿童网站界面设计图片,中国少年儿童教育网站-怎么去注册?
佛山企业网站制作公司有哪些,沟通100网上服务官网?
如何制作公司的网站链接,公司想做一个网站,一般需要花多少钱?
如何在阿里云部署织梦网站?
网站图片在线制作软件,怎么在图片上做链接?
5种Android数据存储方式汇总
青岛网站建设如何选择本地服务器?
PHP 500报错的快速解决方法
Laravel如何从数据库删除数据_Laravel destroy和delete方法区别
Laravel Fortify是什么,和Jetstream有什么关系
专业型网站制作公司有哪些,我设计专业的,谁给推荐几个设计师兼职类的网站?

