在Java中有对象锁和类锁的区别,我们直接看demo来说明
public class Demo1 {
public static final Object LOCK=new Object();
//对象锁,锁为当前对象
public synchronized void a() throws Exception{
System.out.println("a.................begin");
Thread.sleep(1000);
System.out.println("a.................end");
}
//对象锁,锁为当前对象
public synchronized void b() throws Exception{
System.out.println("b..................begin");
Thread.sleep(1000);
System.out.println("b.................end");
}
//类锁,锁为方法所属于的类
public static synchronized void c() throws Exception{
System.out.println("c..................begin");
Thread.sleep(1000);
System.out.println("c.................end");
}
//对象锁,锁为指定的对象
public void d() throws InterruptedException{
synchronized(LOCK){
System.out.println("d..................begin");
Thread.sleep(1000);
System.out.println("d.................end");
}
}
//对象锁,锁为当前对象
public void e() throws InterruptedException{
synchronized(this){
System.out.println("e..................begin");
Thread.sleep(1000);
System.out.println("e.................end");
}
}
//类锁,锁为class类
public void f() throws InterruptedException{
synchronized(Demo1.class){
System.out.println("f..................begin");
Thread.sleep(1000);
System.out.println("f.................end");
}
}
public static void main(String[] args){
Demo1 demo1=new Demo1();
Demo1 demo2=new Demo1();
Thread thread1=new Thread(new Runnable() {
@Override
public void run() {
try {
demo1.a();
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
});
Thread thread2=new Thread(new Runnable() {
@Override
public void run() {
try {
demo2.b();
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
});
thread1.start();
thread2.start();
}
}
运行结果:
a.................begin
b..................begin
b.................end
a.................end
可以看出,线程2并不是等着线程1执行完释放锁才执行,那是因为他们俩要竞争的都不是同一把锁,这里有两个运行类,demo1和demo2,而线程1和线程2的锁就分别对应着这两个对象。
我们在看一个类锁的例子,这里我们只需要改main函数来执行就可以:
public static void main(String[] args){
Demo1 demo1=new Demo1();
Demo1 demo2=new Demo1();
Thread thread1=new Thread(new Runnable() {
@Override
public void run() {
try {
demo1.c();//注意执行的是c方法
} catch (Exception e) {
e.printStackTrace();
}
}
});
Thread thread2=new Thread(new Runnable() {
@Override
public void run() {
try {
demo2.f();//注意执行的是f方法
} catch (Exception e) {
e.printStackTrace();
}
}
});
thread1.start();
thread2.start();
}
运行结果:
c..................begin
c.................end
f..................begin
f.................end
这里可以看出结果是我们预想的同步的。因为c和f方法都是类锁,线程1和线程2竞争的锁都可以看做是Demo1.class,所以当1获得锁后,线程2必须要等到线程1释放才能进入方法执行。