一本书讲透Java线程:原理与实践
上QQ阅读APP看本书,新人免费读10天
设备和账号都新为新人

1.5 线程同步:互斥量

线程的主要优势在于能够通过全局变量来共享信息。不过这也带来一个问题:多个线程如何安全地修改同一变量?代码清单1-12是一个线程不安全的例子:先定义了countTask函数,函数的基本功能就是完成全局变量total的100万次自增。在main函数中创建了两个线程,同时完成对total的自增计算。

代码清单1-12 线程不安全例子

程序期望的执行结果应该是200万,而实际运行的结果大相径庭,而且每次运行的结果都不一致。运行结果如下:

数据不一致的原因是多线程同时操作total+1。为避免多线程在更新共享变量时出现不一致,Linux提供了互斥量mutex。mutex确保在同一时刻仅有一个线程可以访问某共享资源,从而保证对共享资源的原子性访问。互斥量有两种状态:已锁定状态(locked)和未锁定状态(unlocked)。在任何时刻都只有一个线程可以锁定互斥量,一旦线程锁定互斥量,随即成为该互斥量的所有者,其他想获取整个信号量的线程都要进入等待状态。