zoukankan      html  css  js  c++  java
  • 多线程--对象锁和类锁

    一.对象锁和类锁的区别

     对象锁是用于对象实例方法,或者一个对象实例上的,类锁是用于类的静态方法或者一个类的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     }

  • 相关阅读:
    HDFS命令操作和高可用
    nginx-nginx和反向代理概念
    day01 Hadoop 简单介绍及架构设计
    常用正则表达式
    【JavaWeb笔记】第二章 JDBC
    【JavaSE笔记】第二章 进制数据类型和运算符
    LeetCode-94 Binary Tree Inorder Traversal Solution (with Java)
    LeetCode-1019 Next Greater Node In Linked List Solution (with Java)
    LeetCode-946 Validate Stack Sequences Solution (with Java)
    LeetCode-739 Daily Temperatures Solution (with Java)
  • 原文地址:https://www.cnblogs.com/jvStarBlog/p/10887101.html
Copyright © 2011-2022 走看看