Java的锁分为对象锁和类锁。
1. 当两个并发线程访问同一个对象object中的这个synchronized(this)同步代码块时,一个时间内针对该对象的操作只能有一个线程得到执行。另一个线程必须等待当前线程执行完这个代码块以后才能执行该代码块。
2. 然而,另一个线程仍然可以访问该object中的非synchronized(this)同步代码块。
3. 尤其关键的是,当一个线程访问object的一个synchronized(this)同步代码块时,其他线程对该object中所有其它synchronized(this)同步代码块的访问将被阻塞。
4. 同步加锁的是对象,而不是代码。因此,如果你的类中有一个同步方法,这个方法可以被两个不同的线程同时执行,只要每个线程自己创建一个的该类的实例即可。
5. 不同的对象实例的synchronized方法是不相干扰的。也就是说,其它线程照样可以同时访问相同类的另一个对象实例中的synchronized方法。
6. synchronized关键字是不能继承的,也就是说,基类的方法synchronized f(){} 在继承类中并不自动是synchronized f(){},而是变成了f(){}。继承类需要你显式的指定它的某个方法为synchronized方法。
7.对一个全局对象或者类加锁时,对该类的所有对象都起作用。
类锁举例
对一个全局变量加锁:
- 1 public class MySynchronizedextends Thread
- 2 {
- 3 private int val;
- 4
- 5 private static Object lock = new Object();
- 6
- 7 public MySynchronized(int v)
- 8 {
- 9 val = v;
- 10 }
- 11
- 12 public void printVal(int v)
- 13 {
- 14 synchronized (lock)
- 15 {
- 16 while (true)
- 17 {
- 18 System.out.println(v);
- 19 }
- 20 }
- 21 }
- 22
- 23 public void run()
- 24 {
- 25 printVal(val);
- 26 }
- 27 }
对整个类加锁:
- 1 public class MySynchronized extends Thread
- 2 {
- 3 private int val;
- 4
- 5 public MySynchronized(int v)
- 6 {
- 7 val = v;
- 8 }
- 9
- 10 public void printVal(int v)
- 11 {
- 12 synchronized (MySynchronized.class)
- 13 {
- 14 while (true)
- 15 {
- 16 System.out.println(v);
- 17 }
- 18 }
- 19 }
- 20
- 21 public void run()
- 22 {
- 23 printVal(val);
- 24 }
- 25 }
另外的锁例子
String常量的特殊性,属于同一个对象。
- public class MySynchronizedextends Thread
- {
- private String name;
- private String val;
- public MySynchronized(String name, String v)
- {
- this.name = name;
- val = v;
- }
- public void printVal()
- {
- synchronized (val)
- {
- while (true)
- {
- System.out.println(name + val);
- }
- }
- }
- public void run()
- {
- printVal();
- }
- public static void main(String args[])
- {
- MySynchronized f1 = new MySynchronized("Foo 1:","printVal");
- f1.start();
- MySynchronized f2 = new MySynchronized("Foo 2:","printVal");
- f2.start();
- }
- }