数码知识屋
霓虹主题四 · 更硬核的阅读氛围

线程安全与并发的区别:别再傻傻分不清(实用技巧版)

发布时间:2025-12-14 21:21:00 阅读:0 次

写代码时经常听到“这个类是线程安全的”或者“这段逻辑要考虑并发问题”,听起来好像差不多,其实完全是两个层面的事。就像做饭时“食材新鲜”和“多人同时下厨”不是一回事,线程安全和并发也得分开看。

并发是场景,线程安全是应对

并发指的是多个任务在同一时间段内交替执行,比如你一边刷视频一边回微信,手机系统就在处理并发。程序里也一样,一个服务同时接100个用户请求,这些请求对应的线程可能同时操作同一个数据。

这时候问题就来了:如果两个线程同时修改同一个余额变量,一个减50,一个减30,原本1000的余额,结果可能只减了50或30,甚至变成奇怪的数字。这不是因为程序写错了语法,而是没有应对好并发带来的竞争。

线程安全是代码的“防踩踏设计”

线程安全指的是某个类、方法或代码块在多线程环境下执行时,依然能表现出正确的行为。就像地铁站的闸机,不管多少人同时刷卡,系统都能准确记录进出人数,不会漏记或多记。

举个例子,下面这个计数器就不是线程安全的:

public class Counter {
    private int count = 0;

    public void increment() {
        count++; // 这一行其实包含读、加、写三步
    }

    public int getCount() {
        return count;
    }
}

因为 count++ 不是原子操作,两个线程可能同时读到相同的值,各自加1后再写回去,结果只增加了1次。要让它线程安全,可以加锁:

public class SafeCounter {
    private int count = 0;

    public synchronized void increment() {
        count++;
    }

    public synchronized int getCount() {
        return count;
    }
}

加上 synchronized,就像给方法加了门,同一时间只能有一个线程进来,避免了数据冲突。

有并发不一定需要线程安全

也不是所有并发场景都要追求线程安全。比如你写的工具类只在单线程里用,就算它不安全也没关系。就像家里只有一个厨房,没人抢灶台,自然不需要排班表。

反过来,即使没有并发,谈线程安全也没意义。单线程环境里,代码怎么跑都出不了问题,安全不安全根本没区别。

常见误区

很多人以为用了线程安全的集合类(比如 ConcurrentHashMap)就万事大吉,其实不然。它只能保证自己内部操作是安全的,如果你在外面做“先查后改”这种组合操作,依然可能出问题。

比如:

if (!map.containsKey("key")) {
    map.put("key", "value"); // 中间可能被其他线程插队
}

即便 mapConcurrentHashMap,这段代码仍然可能让两个线程同时写入,导致重复操作。正确的做法是直接用 putIfAbsent 这种原子方法。

说到底,并发是现实,线程安全是应对策略。搞清楚谁是因,谁是果,写多线程代码时才不会手忙脚乱。