zoukankan      html  css  js  c++  java
  • java多线程关于“对象锁”的理解

    本文参考转载自:http://jasshine.iteye.com/blog/1617813

    关于对象锁,其实这个对象指的是拥有synchronized修饰的函数,或者是代码块的一个类的实例。 当某个线程访问该类的方法或synchronized修饰的代码快时,就获得该对象的锁,其他线程就无法获得该对象的锁,也就是说这个对象已经被前一个线程所占用,另外的线程无法得到该对象,所以该对象对应的方法也就无法访问,必须等到前一个线程释放对象锁才可能有机会得到对象锁。

     1 package main.java;
     2 
     3 public class CSD implements  Runnable {
     4     int a;
     5     public void run() {
     6         synchronized (this) {
     7             a++;
     8             System.out.println("当前线程名为:"+Thread.currentThread().getName()+",a:"+a);
     9             try {
    10                 Thread.sleep(5000);//休眠5秒
    11             } catch (InterruptedException e) {
    12                 e.printStackTrace();
    13             }
    14         }
    15         
    16     }
    17 
    18 }
    package main.java;
    
    public class TestCSD {
    	
    	public static void main(String[] args) {
    		CSD csd1  = new CSD();
    		CSD csd2  = new CSD();
    		Thread thread  = new Thread(csd1);
    		Thread thread2  = new Thread(csd1);
    		thread.start();
    		thread2.start();
    		
    	}
    
    }
    

    测试结果:

    当前线程名为:Thread-0,a:1

    隔5秒钟
    当前线程名为:Thread-1,a:2              

    or    

    当前线程名为:Thread-1,a:1

    隔5秒钟
    当前线程名为:Thread-0,a:2                                                                                                                                                                                              

    解释结果:                                                                                                                                                                          
    因为加了synchronzied,实现了同步,并且该对象锁对应的对象只有一个,那就是csd1,所以当第一个线程锁住了csd1,而第二个线程里面也是通过csd1去访问run()方法,所以必须等第一个线程执行完对象的方法时才能获得对象锁。因此必须隔5秒钟才能执行当前线程

    TestCSD修改:Thread thread2  = new Thread(csd1);改为Thread thread2  = new Thread(csd2);

    测试结果:

    当前线程名为:Thread-1,a:1
    当前线程名为:Thread-0,a:1

    or 

    当前线程名为:Thread-0,a:1
    当前线程名为:Thread-1,a:1

    解释:因为此时每个线程都是通过不同的对象去访问run()方法,一个为csd1,另外一个为csd2,所以有两把对象锁,这两个对象锁毫不干,第一个线程锁住了csd1,而第二个线程都是通过
    csd2对象去访问的,所以仍然能访问该方法。


    上面的一个简单程序足以说明同步方法,和对象锁的概念了。总结一下:

    1. java中的每个对象都有一个锁,当访问某个对象的synchronized方法时,表示将该对象上锁,此时其他任何线程都无法在去访问该syncronized 方法了,直到之前的那个线程执行方法完毕后,其他线程才有可能去访问该synchronized方法。

    2.如果一个对象有多个synchronized方法,某一时刻某个线程已经进入到某个synchronzed方法,那么在该方法没有执行完毕前,其他线程无法访问该对象的任何synchronzied 方法的,但可以访问非synchronzied方法。

    3.如果synchronized方法是static的,那么当线程访问该方法时,它锁的并不是synchronized方法所在的对象,而是synchuronized方法所在对象的对应的Class对象,
    因为java中无论一个类有多少个对象,这些对象会对应唯一一个Class 对象,因此当线程分别访问同一个类的两个对象的static,synchronized方法时,他们的执行也是按顺序来的,也就是说一个线程先执行,一个线程后执行。 

      

  • 相关阅读:
    古谚、评论与论断、名篇与名言
    重读《西游记》
    重读《西游记》
    命名之法 —— 时间、季节、地点
    命名之法 —— 时间、季节、地点
    文言的理解 —— 古时的称谓、别称、别名
    文言的理解 —— 古时的称谓、别称、别名
    Oracle GoldenGate for Oracle 11g to PostgreSQL 9.2.4 Configuration
    瀑布 敏捷 文档
    POJ 1325 ZOJ 1364 最小覆盖点集
  • 原文地址:https://www.cnblogs.com/whhjava/p/7827020.html
Copyright © 2011-2022 走看看