多线程--对象锁和类锁

时间:2022-02-15 13:03:48

一.对象锁和类锁的区别

 对象锁是用于对象实例方法,或者一个对象实例上的,类锁是用于类的静态方法或者一个类的class对象上的。我们知道,类的对象实例可以有很多个,但是每个类只有一个class对象,所以不同对象实例的对象锁是互不干扰的,但是每个类只有一个类锁。但是有一点必须注意的是,其实类锁只是一个概念上的东西,并不是真实存在的,它只是用来帮助我们理解锁定实例方法和静态方法的区别的。

同步控制的范围越小,并发性能越好;反之,并发性能越差。一般来说,并发性能由高到底,synchronized 代码块>synchronized 同步方法>类锁。

二.对象锁

  1.对象锁只针对同一个实例对象中synchronized 修饰的部分实现同步,对同一个类下的多个对象、同一个对象的非synchronized 修饰的部分不会阻塞 。

 1 public class MyObject {
 2     //加对象锁
 3     public synchronized void method1(){
 4         System.out.println("method1 start----");
 5         try {
 6             Thread.sleep(5000);
 7         } catch (InterruptedException e) {
 8             e.printStackTrace();
 9         }
10         System.out.println("method1 end----");
11     }
12 
13     //加对象锁
14     public synchronized void method2(){
15         System.out.println("method2 start----");
16         try {
17             Thread.sleep(5000);
18         } catch (InterruptedException e) {
19             e.printStackTrace();
20         }
21         System.out.println("method2 end----");
22     }
23 
24     //不加锁
25     public  void method3(){
26         System.out.println("method3 start----");
27         try {
28             Thread.sleep(5000);
29         } catch (InterruptedException e) {
30             e.printStackTrace();
31         }
32         System.out.println("method3 end----");
33     }
34 }

 多线程操作同一个对象synchronized 修饰的部分,一个线程必须等待前一个线程的对象锁释放之后才开始执行,线程执行顺序不确定,运行结果如下:

 1      //同一个实例对象
 2         final MyObject obj1=new MyObject();
 3         new Thread(new Runnable() {
 4             @Override
 5             public void run() {
 6                 obj1.method1();
 7             }
 8         }).start();
 9 
10         new Thread(new Runnable() {
11             @Override
12             public void run() {
13                 obj1.method2();
14             }
15         }).start();

多线程--对象锁和类锁

多线程操作不同对象,对象锁无效,运行结果如下:

 1         //不同实例对象
 2         final MyObject obj1=new MyObject();
 3         final MyObject obj2=new MyObject();
 4         new Thread(new Runnable() {
 5             @Override
 6             public void run() {
 7                 obj1.method1();
 8             }
 9         }).start();
10 
11         new Thread(new Runnable() {
12             @Override
13             public void run() {
14                 obj2.method2();
15             }
16         }).start();    

多线程--对象锁和类锁

多线程操作同一对象的同步方法和非同步方法,彼此之间互不影响,不会发生阻塞,运行结果如下:

 1         //同一对象
 2         final MyObject obj1=new MyObject();
 3         new Thread(new Runnable() {
 4             @Override
 5             public void run() {
 6                 obj1.method1();
 7             }
 8         }).start();
 9 
10         new Thread(new Runnable() {
11             @Override
12             public void run() {
13                 obj1.method3();
14             }
15         }).start();
16     }    

多线程--对象锁和类锁

三.类锁

 类锁是锁住整个类,不管有多少个对象,共用一把类锁,且类锁只有一把,不管怎么调用,都会同步。

 1 //加类锁
 2     public synchronized static void method4(){
 3         System.out.println(Thread.currentThread().getName()+" call method4 start----");
 4         try {
 5             Thread.sleep(1000);
 6         } catch (InterruptedException e) {
 7             e.printStackTrace();
 8         }
 9         System.out.println(Thread.currentThread().getName()+" call method4 end----");
10     }
 1 final MyObject obj1 = new MyObject();
 2         final MyObject obj2 = new MyObject();
 3         new Thread(new Runnable() {
 4             @Override
 5             public void run() {
 6                 obj1.method4();
 7             }
 8         }, "thread1").start();
 9 
10         new Thread(new Runnable() {
11             @Override
12             public void run() {
13                 obj1.method4();
14             }
15         }, "thread2").start();
16 
17         new Thread(new Runnable() {
18             @Override
19             public void run() {
20                 obj2.method4();
21             }
22         }, "thread3").start();
23     }

多线程--对象锁和类锁