synchronized关键字,可以放到实例方法的前面,也可以放在类方法(静态方法)前面。
synchronized还可以用来控制代码块。
每个对象都有一把锁,锁是对象级的,
不是方法级的。
我们可以使用synchronized关键字来定义一个边界,受这个边界控制的资源在同一时刻只允许一个线程访问。
边界的范围,是由synzhronized定义的位置决定的,如果synchronized关键字定义在实例方法前面,
则其边界相当于this(this对象),即同一个对象的所有synchronized实例方法在同一时刻只允许一个线程访问。
1.synchronized关键字被添加到实例方法的前面时,只要一个线程访问了其中的一个synchronized方法,
其它线程不能同时访问这个对象中任何一个synchronized方法(对象级的锁)。
2.放在静态方法前面的时候,只有一个线程可以调用这个类的静态方法(任意静态方法)(类级别的锁)
其实,类级别的锁也是通过对象锁来实现的,它实际上在是某个类的字节码所对应的对象上加 锁。
如:
synchronized
(Object.class) {
}
3.判断是否可以并发访问,只需要判断加的锁是不是同一把锁。如果不是同一把锁,则可以并发访问,否则不可以。
4.每个线程都会有一个它自己的栈,所以对于局部变量,不存在并发访问问题。对于实例变量和类变量,有并发访问问题。
ps:
1.共享资源:
●共享资源(或临界资源)问题:多个线程同时修改同一个数据(资源),导致
最终结果不正确,这是典型的由于并发访问所产生的问题。
●线程的内存结构
1.当我们每启动一个线程,每个线程都会有一个它自己的栈,所以对于局部变量,
不存在并发访问问题。
2.但"堆"(heap)和"方法区"是所有线程共享的,所以,如果我们在多个线程中访问
"堆"中的同一个对象的数据时,或者访问静态变量时,就会产生并发访问问题。