【并发编程】类锁和对象锁的区别
类锁和对象锁的区别:
- 对象锁是当前对象实例的锁,只有是同一个对象才会涉及是否做同步
- 类锁故名思议就是这个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对象进行操作,互不冲突。