并发编程中的三个问题有哪些 并发编程的三大问题
导读:并发编程中的三个问题有哪些,今天小编详解并发编程中的三个问题有哪些IT技巧方面的经验,下面小编为您详细解答 1.可见性 可见性(Visibility): 是指一个线程对共享变量进行修改,另一个先立即得
并发编程中的三个问题有哪些
今天小编详解并发编程中的三个问题有哪些IT技巧方面的经验,下面小编为您详细解答
1.可见性
可见性(Visibility):是指一个线程对共享变量进行修改,另一个先立即得到修改后的最新值
1.1 可见性案例演示
一个线程根据boolean类型的标记flag, while循环,另一个线程改变这个flag变量的值,另 一个线程并不会停止循环
public class VisibilityTest {
// 多个线程都会访问的数据,我们称为线程的共享数据
// 定义一个静态的 boolean 变量 run,初始值为 true
private static boolean run = true;
public static void main(String[] args) throws InterruptedException {
// 创建并启动线程 t1
Thread t1 = new Thread(() -> {
// 在 run 变量为 true 时循环输出消息
while (run) {
System.out.println(Thread.currentThread().getName() + "线程1 run = " + run);
}
// 循环结束后输出最终消息
System.out.println(Thread.currentThread().getName() + "线程1 run = " + run);
});
t1.start(); // 启动线程 t1
Thread.sleep(1000); // 主线程睡眠1秒钟
// 创建并启动线程 t2
Thread t2 = new Thread(() -> {
run = false; // 将 run 变量设置为 false
System.out.println(Thread.currentThread().getName() + "时间到,线程2设置为false");
});
t2.start(); // 启动线程 t2
}
}
一个线程根据boolean类型的标记flag, while循环,另一个线程改变这个flag变量的值,另 一个线程并不会停止循环
public class VisibilityTest {
// 多个线程都会访问的数据,我们称为线程的共享数据
// 定义一个静态的 boolean 变量 run,初始值为 true
private static boolean run = true;
public static void main(String[] args) throws InterruptedException {
// 创建并启动线程 t1
Thread t1 = new Thread(() -> {
// 在 run 变量为 true 时循环输出消息
while (run) {
System.out.println(Thread.currentThread().getName() + "线程1 run = " + run);
}
// 循环结束后输出最终消息
System.out.println(Thread.currentThread().getName() + "线程1 run = " + run);
});
t1.start(); // 启动线程 t1
Thread.sleep(1000); // 主线程睡眠1秒钟
// 创建并启动线程 t2
Thread t2 = new Thread(() -> {
run = false; // 将 run 变量设置为 false
System.out.println(Thread.currentThread().getName() + "时间到,线程2设置为false");
});
t2.start(); // 启动线程 t2
}
}输出结果:
Thread-0线程1 run = true
Thread-0线程1 run = true
// .....结果省略
Thread-1时间到,线程2设置为false
Thread-0线程1 run = false
线程1开始运行时run=true,所以会不断循环输出Thread-0线程1 run = true,线程2运行后设置run=false,线程1发现run=true后就停止输出
总结:并发编程时,会出现可见性问题,当一个线程对共享变量进行了修改,另外的线程并没有立即看到修改 后的最新值。
2.原子性
原子性(Atomicity):在一次或多次操作中,要么所有的操作都执行并且不会受其他因素干扰而中断,要么所有的操作都不执行
2.1 可见性案例演示
5个线程各执行1000次 i++
public class AtomicityTest {
private static int number = 0; // 定义一个静态的整数变量 number,初始值为 0
public static void main(String[] args) throws InterruptedException {
Runnable increment = () -> {
// 定义一个 Runnable 匿名类 increment,用于对 number 进行累加操作
for (int i = 0; i < 1000; i++) {
number++; // 对 number 进行累加操作
}
};
ArrayList<Thread> ts = new ArrayList<>(); // 创建一个 ArrayList 用于存储线程对象
for (int i = 0; i < 5; i++) {
Thread t = new Thread(increment); // 创建一个新线程,传入 increment Runnable 实例
t.start(); // 启动线程
ts.add(t); // 将线程对象添加到 ArrayList 中
}
for (Thread t : ts) {
t.join(); // 等待所有子线程执行完毕
}
System.out.println("number = " + number); // 输出最终的 number 值
}
}
5个线程各执行1000次 i++
public class AtomicityTest {
private static int number = 0; // 定义一个静态的整数变量 number,初始值为 0
public static void main(String[] args) throws InterruptedException {
Runnable increment = () -> {
// 定义一个 Runnable 匿名类 increment,用于对 number 进行累加操作
for (int i = 0; i < 1000; i++) {
number++; // 对 number 进行累加操作
}
};
ArrayList<Thread> ts = new ArrayList<>(); // 创建一个 ArrayList 用于存储线程对象
for (int i = 0; i < 5; i++) {
Thread t = new Thread(increment); // 创建一个新线程,传入 increment Runnable 实例
t.start(); // 启动线程
ts.add(t); // 将线程对象添加到 ArrayList 中
}
for (Thread t : ts) {
t.join(); // 等待所有子线程执行完毕
}
System.out.println("number = " + number); // 输出最终的 number 值
}
}
相关阅读
-
深入解析:MySQL常用优化技巧及方法
正文核心导读:的内容,具体内容如下: 在数据库管理和应用开发中,性能优化是一个重要的环节。 特别是在处理大量数据和复杂查询时,一个优化得当的MySQL数据库可以大大提高应用程序的
-
OSI七层网络模型物理层详解 物理层的主要功能和特点有哪些
下面为网友们详细介绍OSI七层网络模型物理层详解的相关话题,接下来一起来看看吧。 物理层是OSI模型中的第一层,它负责在物理媒介上传输原始比特流,并定义了传输介质、传输速率、编码
-
lol国服查询实时排名网站 英雄联盟排行榜查询方法
文章导读:lol国服查询实时排名网站和英雄联盟排行榜查询方法的相关知识,接下来一起来看看吧。 在英雄联盟手游中玩家们进行排位赛以后是有评分和排名的,不过对于新手玩家们来说可能
-
mysql:replica_skip_errors参数配置推荐
IT袋网网为大家说一说mysql的介绍,相关内容具体如下: MySQL的 replica_skip_errors 参数允许用户指定要在复制过程中跳过的错误类型。 当出现指定错误时,从服务器不会停止复制,而是跳过错误继


