下面是自己的理解+代码:

一.前置知识:

但是有一点必须注意的是,其实类锁只是一个概念上的东西,并不是真实存在的,它只是用来帮助我们理解锁定实例方法和静态方法的区别的

二.代码理解

  1. synchronized(对象锁):两种;
synchronized(this){ 
//互斥代码
} 
或:
private Object lock = new Object();
public void test1(){
    synchronized(lock){ 
    //互斥代码
    }
}

这里的this,指的是调用它的实例对象,即锁就是这个这里对象 ; 而lock锁则是任意对象锁(所有需要这个对象的锁的方法都不能同时执行),有些许的不同(所有线程线程能共用该锁)。

  1. 代码:
Ticket t1=new Ticket();   Ticket t2=new Ticket(); Ticket t3=new Ticket();
t1.start();     t2.start();   t3.start();
//测试三个线程 	   
class Ticket extends Thread{
    private int num=100;
    //Object obj = new Object();
    public void run() {
	while(true) {
            //synchronized (obj) 
            synchronized (this) {
               if(num>0)System.out.println(Thread.currentThread().getName()+".."+num--);                  
	        try {
		    Thread.sleep(100);
		}catch (Exception e) {}
	    }
		System.out.println(Thread.currentThread().getName()+":释放");
        }
    }
}

java object对象锁 java 对象锁 类锁_对象锁

此时线程1.2.0.交替执行,但注意下一次线程1.2.0像执行必须对应锁释放,换句话说这里三个线程对象对应了三个锁,只锁自己,不能锁别人,cpu可以切换其他线程执行,只要没被锁。  而代码注释的第二种结果是:                 

java object对象锁 java 对象锁 类锁_静态方法_02

与上面同理,也是只能锁自己。是把当前这个对象的成员变量(object)当做锁,其实三个线程对象有三个不同的object对象,因为这个变量不共享。

  1. tips:这样加锁的好处 (这是最常用的高并发场景下要锁住某个方法所用的操作)
private Object lock = new Object();
public void test1(){
    synchronized(lock){ 
    //互斥代码
    }
}
private static Object lock = new Object();

但如果任意对象锁改为静态的,则可以实现互斥了,所有线程共享这个锁(共享这个变量)。                                       

java object对象锁 java 对象锁 类锁_互斥_03

  1. synchronized(类锁)
  2. 对于类锁来说其实和对象锁一样只是为了区别静态方法和普通方法,对于多个线程,都是一把锁,和第5点的情况一样
synchronized(A.class){ 
//互斥代码
}

tips:object.getClass()和A.class实际意义不同,并且对于前者来说,出现多态时,可能会有问题

  1. 每个线程执行都得等内阁唯一的一把锁释放。

三:一点解释:

    Thread.sleep():强制线程休眠未来*ms时间内不进入CPU进行竞争,进入阻塞状态,给其他线程机会执行,但是,他不会释放锁;且 *毫秒过去之后,这时候也许另外一个线程正在使用CPU,那么这时候操作系统是不会重新分配CPU的, 直到那个线程挂起或结束;况且,即使这个时候恰巧轮到操作系统进行CPU 分配,那么当前线程也不一定就是总优先级最高的那个,CPU还是可能被其他线程抢占去。也不一定会论到调度他。

    线程获得对象锁的同时,也可以获得该类锁,即同时获得两个锁,这是允许的。