网站首页 > java教程 正文
Java多线程的三大特性是原子性、可见性和有序性。下面我会用代码分别说明这三个特性。
1、原子性(Atomicity):指一个操作是不可中断的,要么全部执行成功,要么全部不执行。在多线程环境下,原子性可以通过synchronized关键字或java.util.concurrent.atomic包中的原子类来实现。
使用原子类实现原子性
import java.util.concurrent.atomic.AtomicInteger;
public class AtomicityExample {
private static AtomicInteger counter = new AtomicInteger(0);
public static void main(String[] args) throws InterruptedException {
Thread t1 = new IncrementThread();
Thread t2 = new IncrementThread();
t1.start();
t2.start();
t1.join();
t2.join();
System.out.println("Counter: " + counter);
}
static class IncrementThread extends Thread {
@Override
public void run() {
for (int i = 0; i < 1000; i++) {
counter.incrementAndGet();
}
}
}
}
在上述示例中,使用AtomicInteger保证了counter变量的原子性。两个执行递增操作的线程同时对counter进行操作,但由于AtomicInteger的原子性保证,最终结果将是2000。
使用synchronized关键字实现原子性
public class AtomicityExample {
private static int counter = 0;
public static void main(String[] args) throws InterruptedException {
Thread t1 = new IncrementThread();
Thread t2 = new IncrementThread();
t1.start();
t2.start();
t1.join();
t2.join();
System.out.println("Counter: " + counter);
}
static class IncrementThread extends Thread {
@Override
public void run() {
for (int i = 0; i < 1000; i++) {
synchronized (AtomicityExample.class) {
counter++;
}
}
}
}
}
在这个例子中,我们使用AtomicInteger类作为计数器。AtomicInteger提供了一系列原子操作,例如incrementAndGet()方法可以原子地递增计数器的值。这样就确保了对计数器的操作是原子的。
通过以上两个示例,我们可以看到如何实现原子性操作。无论是使用synchronized关键字还是使用原子类,目的都是确保对共享数据的操作是原子的,避免多线程环境下的竞争条件和数据不一致问题。
2、可见性(Visibility):指当一个线程修改了共享变量的值后,其他线程能够立即看到修改后的值。在多线程环境下,可见性问题可以通过synchronized关键字或volatile关键字来解决。
public class VisibilityExample {
private static volatile boolean flag = false;
public static void main(String[] args) throws InterruptedException {
Thread t1 = new ChangeFlagThread();
Thread t2 = new ReadFlagThread();
t1.start();
t2.start();
t1.join();
t2.join();
}
static class ChangeFlagThread extends Thread {
@Override
public void run() {
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
flag = true;
System.out.println("Flag is changed.");
}
}
static class ReadFlagThread extends Thread {
@Override
public void run() {
while (!flag) {
// 空循环等待flag的修改
}
System.out.println("Flag is read.");
}
}
}
在上述示例中,一个线程修改了flag的值为true,另一个线程不断检查flag的值是否为true。由于使用了volatile关键字,当一个线程修改了flag的值后,另一个线程能够立即看到修改后的值。
3、有序性(Ordering):指程序执行的顺序与代码的顺序一致。在多线程环境下,由于指令重排序和缓存一致性等因素,可能会导致代码执行的顺序与代码的编写顺序不一致,可以通过synchronized关键字或java.util.concurrent包中的锁来保证代码的有序性。
public class OrderingExample {
private static int x = 0;
private static int y = 0;
private static boolean flag = false;
public static void main(String[] args) throws InterruptedException {
Thread t1 = new WriteThread();
Thread t2 = new ReadThread();
t1.start();
t2.start();
t1.join();
t2.join();
}
static class WriteThread extends Thread {
@Override
public void run() {
x = 1;
flag = true;
}
}
static class ReadThread extends Thread {
@Override
public void run() {
if (flag) {
y = x;
}
System.out.println("y: " + y);
}
}
}
在上述示例中,一个线程先修改了x的值为1,再将flag设置为true。另一个线程检查到flag为true时,读取x的值,并将其赋给y。由于缺乏同步机制,可能会发生指令重排序,导致在第二个线程中y的值为0。如果使用synchronized关键字或锁来保证同步,可以避免指令重排序,保证代码执行的有序性。
- 上一篇: 好程序员Java学习路线分享三大特性之多态
- 下一篇: Java-面向对象三大基本特性,五大基本原则
猜你喜欢
- 2024-10-07 java 面对对象的三大特性——面试的时候一直在看,面试官很满意
- 2024-10-07 第三章 java内存模型与并发三大特性
- 2024-10-07 理解Java的三大特性之封装(java的封装是什么)
- 2024-10-07 揭秘Java五大特性,你不容错过!(java的基本特性)
- 2024-10-07 JAVA基础——面向对象三大特性:封装、继承、多态
- 2024-10-07 Java有哪些特性?(请简述java有哪些特性)
- 2024-10-07 Java-面向对象三大基本特性,五大基本原则
- 2024-10-07 好程序员Java学习路线分享三大特性之多态
- 2024-10-07 Java 12 新特性概述(java语言具有较好的安全性和可移植性及与平台无关等特性)
- 2024-10-07 Java知识扫盲:Java的11大主要特性总结
你 发表评论:
欢迎- 最近发表
- 标签列表
-
- java反编译工具 (77)
- java反射 (57)
- java接口 (61)
- java随机数 (63)
- java7下载 (59)
- java数据结构 (61)
- java 三目运算符 (65)
- java对象转map (63)
- Java继承 (69)
- java字符串替换 (60)
- 快速排序java (59)
- java并发编程 (58)
- java api文档 (60)
- centos安装java (57)
- java调用webservice接口 (61)
- java深拷贝 (61)
- 工厂模式java (59)
- java代理模式 (59)
- java.lang (57)
- java连接mysql数据库 (67)
- java重载 (68)
- java 循环语句 (66)
- java反序列化 (58)
- java时间函数 (60)
- java是值传递还是引用传递 (62)
本文暂时没有评论,来添加一个吧(●'◡'●)