11 临界区与竞态条件
11 临界区与竞态条件
临界区 Critical Section
-
一个程序运行多个线程本身是没有问题的
-
问题出在多个线程访问共享资源
-
多个线程读共享资源其实也没有问题
-
在多个线程对共享资源读写操作时发生指令交错,就会出现问题
-
-
一段代码块内如果存在对共享资源的多线程读写操作,称这段代码块为临界区
例如,下面代码中的临界区:
static int counter = 0;
static void increment()
// 临界区
{
counter++;
}
static void decrement()
// 临界区
{
counter--;
}
竞态条件 Race Condition
多个线程在临界区内执行,由于代码的执行序列不同而导致结果无法预测,称之为发生了竞态条件。
临界区资源加锁和不加锁的代码演示
//对临界区不加锁,会产生不正确的答案 public class CriticalZoneAndLock { static int count = 0; static Object lock = new Object(); public static void main(String[] args) throws InterruptedException { Runnable task1 = new Runnable() { @Override public void run() { //对临界区资源加同一把锁 // synchronized (lock){ //临界区 for (int i = 0; i < 5000; i++) { count++; } // } } }; Runnable task2 = new Runnable() { @Override public void run() { //对临界区资源加同一把锁 //synchronized (lock){ //临界区 for (int i = 0; i < 5000; i++) { count--; } } //} }; Thread t1 = new Thread(task1, "t1"); Thread t2 = new Thread(task2, "t2"); t1.start(); t2.start(); t1.join(); t2.join(); System.out.println(count); } }
结果:
-272(这个数是随机的)
public class CriticalZoneAndLock { static int count = 0; static Object lock = new Object(); public static void main(String[] args) throws InterruptedException { Runnable task1 = new Runnable() { @Override public void run() { //对临界区资源加同一把锁 synchronized (lock) { //临界区 for (int i = 0; i < 5000; i++) { count++; } } } }; Runnable task2 = new Runnable() { @Override public void run() { //对临界区资源加同一把锁 synchronized (lock) { //临界区 for (int i = 0; i < 5000; i++) { count--; } } } }; Thread t1 = new Thread(task1, "t1"); Thread t2 = new Thread(task2, "t2"); t1.start(); t2.start(); t1.join(); t2.join(); System.out.println(count); } }
结果:
0
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 终于写完轮子一部分:tcp代理 了,记录一下
· 震惊!C++程序真的从main开始吗?99%的程序员都答错了
· 别再用vector<bool>了!Google高级工程师:这可能是STL最大的设计失误
· 单元测试从入门到精通
· 【硬核科普】Trae如何「偷看」你的代码?零基础破解AI编程运行原理