进行多线程编程的时候,需要考虑的是线程间的同步问题。对于共享的资源,需要进行互斥的访问。在Java中可以使用一些手段来达到线程同步的目的:
1. synchronized
2. ThreadLocal,线程本地变量
3. Java.util.concurrent.Lock
Java中,线程会共享堆上的实例变量以及方法区的类变量,而栈上的数据是私有的,不必进行保护。synchronized方法或synchronized块将标记一块监视区域,线程在进入该区域时,需要获得对象锁或类锁,JVM将自动上锁。synchronized提供了两种主要特性:
1. 互斥。互斥是指一次只允许一个线程持有某个特定的锁,因此可使用该特性实现对共享数据的并发访问,保证一次只有一个线程能够使用该共享数据。
2.可见性。确保释放锁之前对共享数据做出的更改对随后获得该锁的另一个线程是可见的。如果不能保证可见性,也就无法保证数据正确性,这将引发严重问题。volitail关键字同样保证了这种可见性。
在这里,我们将探讨synchronized使用时的三种情况:
1. 在对象上使用synchronized
2. 在普通成员方法上使用synchronized
3. 在静态成员方法上使用synchronized
这三种线程同步的表现有何不同?
下面通过三段示例代码来演示这三种情况。这里模拟线程报数的场景。
情况一:在普通成员函数上使用synchronized
public class MyThread extendsThread {public static void main(String[] args) throwsExcep