类锁和对象锁的区别:

  • 对象锁是当前对象实例的锁,只有是同一个对象才会涉及是否做同步
  • 类锁故名思议就是这个class的锁,只要是同类,即使不同的对象也必须同步

 

例子:

先做一个Person的对象做为锁。代码如下:

public class Person {
    String name;
    String age;
    public Person() {
    }
 
    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public String getAge() {
        return age;
    }

    public void setAge(String age) {
        this.age = age;
    }
 
    public synchronized void test1(Person person){
        System.out.println("name:"+person.getName());
    }
}

 

通过实现Runnable来创建线程对象

public class ThreadTest implements Runnable{
    Person o1;

    public ThreadTest(Person o1) {
        this.o1 = o1;
    }
 
    @Override
    public void run() {
        test();
    }

    public void test(){

        synchronized (Person.class){ //请注意这里 如果这里换成o1 则是对具体的某个对象加锁
            for (int i=0;i<10;i++) {
                try {
                    Thread.sleep(1000);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }       
            System.out.println("ThreadName;"
                +Thread.currentThread().getName()+"hello:"+o1.getName());
            }
        }
    }
}

 

测试类

public class ReentrantLockTest {

    public static void main(String[] args) {
        Person p1=new Person();
        p1.setName("p1");
        Person p2=new Person();
        p2.setName("p2");
        ThreadTest threadTest1=new ThreadTest(p1);
        ThreadTest threadTest2=new ThreadTest(p2);
        Thread t1=new Thread(threadTest1);
        Thread t2=new Thread(threadTest2);
        t1.start();
        t2.start();
    }
}

 

结果:

synchronized(Person.class):

ThreadName;Thread-0hello:p1

ThreadName;Thread-0hello:p1

ThreadName;Thread-0hello:p1

ThreadName;Thread-0hello:p1

ThreadName;Thread-0hello:p1

ThreadName;Thread-0hello:p1

ThreadName;Thread-0hello:p1

ThreadName;Thread-0hello:p1

ThreadName;Thread-0hello:p1

ThreadName;Thread-0hello:p1

ThreadName;Thread-1hello:p2

ThreadName;Thread-1hello:p2

ThreadName;Thread-1hello:p2

ThreadName;Thread-1hello:p2

ThreadName;Thread-1hello:p2

ThreadName;Thread-1hello:p2

ThreadName;Thread-1hello:p2

ThreadName;Thread-1hello:p2

ThreadName;Thread-1hello:p2

ThreadName;Thread-1hello:p2

 

synchronized(o1)

ThreadName;Thread-1hello:p2

ThreadName;Thread-0hello:p1

ThreadName;Thread-0hello:p1

ThreadName;Thread-1hello:p2

ThreadName;Thread-0hello:p1

ThreadName;Thread-1hello:p2

ThreadName;Thread-0hello:p1

ThreadName;Thread-1hello:p2

ThreadName;Thread-1hello:p2

ThreadName;Thread-0hello:p1

ThreadName;Thread-0hello:p1

ThreadName;Thread-1hello:p2

ThreadName;Thread-1hello:p2

ThreadName;Thread-0hello:p1

ThreadName;Thread-0hello:p1

ThreadName;Thread-1hello:p2

ThreadName;Thread-1hello:p2

ThreadName;Thread-0hello:p1

ThreadName;Thread-1hello:p2

ThreadName;Thread-0hello:p1

 

 synchronized(Person.class)时会发现,即使是不同的两个person对象也会按照顺序来同步执行。它会保证只要是Person类的实例对象,那么在同一时间只有一个线程对其访问,其他线程只能等待该线程操作完将锁释放后才能进行操作。即相同类的不同的实例共用一个锁,当一个线程执行完后才能执行另一个线程。这里线程0是操作的p1对象,线程1操作的是p2对象,p1和p2都是Person类的两个不同对象,但是因为这里synchronized获取的是类锁,也就是说只要是这个Person类的对象,同一时间就只能有一个线程对其进行操作,所以虽然两个线程操作的是不同的Person对象,但是还是会对两个线程进行同步操作。

 synchronized(o1)的时候会发现只有同一个person对象才会同步,不同的person对象不会发生同步的行为。它只会保证同一个Person类的实例对象在同一时间只能有一个线程对其进行访问,但是如果是Person类的不同对象,是不会进行同步操作的。即不同对象对应不同的锁。这里线程0是操作的p1对象,线程1操作的是p2对象,p1和p2都是Person类的两个不同对象,synchronized获取的是对象锁,也就是说只有相同的Person类对象才会进行同步操作,不同的对象各自是独立的,不会进行同步操作,所以两个线程可以同时对各自的p1,p2对象进行操作,互不冲突。