您的位置:首页 > 编程语言 > Java开发

java synchronized关键字的用法以及锁的等级:对象锁、类锁

2017-05-03 14:14 666 查看
对象锁用于对象实例方法,类锁用于类的静态方法或一个类的class对象。类的对象实例可以有很多,不同对象实例的对象锁互不干扰,而每个类只有一个类锁

他们用来帮助理解锁定实例方法和静态方法的区别

下面是synchronized 代码块和修饰方法

public class TestSynchronized {
public void test1() {
synchronized (this) {
int i = 5;
while (i-- > 0) {
System.out.println(Thread.currentThread().getName() + ":" + i);
try {
Thread.sleep(500);
} catch (InterruptedException e) {

}
}
}
}

public synchronized void test2() {
int i = 5;
while (i-- > 0) {
System.out.println(Thread.currentThread().getName() + ":" + i);
try {
Thread.sleep(500);
} catch (InterruptedException e) {

}
}
}

public static void main(String[] args) {
final TestSynchronized t = new TestSynchronized();
Thread test1 = new Thread(new Runnable() {

@Override
public void <
4000
span class="hljs-title">run() {
t.test1();
}
}, "test1");

Thread test2 = new Thread(new Runnable() {

@Override
public void run() {
t.test2();
}
}, "test2");
test1.start();
test2.start();
}
}


运行结果

test2:4
test2:3
test2:2
test2:1
test2:0
test1:4
test1:3
test1:2
test1:1
test1:0


两个两种方法都属于方法锁或对象锁,这说明两个同步代码所需要获得的对象锁都是同一个对象锁

当把test2方法synchronized 关键字去掉,执行结果是这样的

test2:4
test1:4
test2:3
test1:3
test1:2
test2:2
test1:1
test2:1
test1:0
test2:0


交替输出说明一个线程同步获得对象锁,但另一个线程没有进行同步,所以他们互不影响

类锁的修饰(静态)方法和代码块

public class TestSynchronized {
public void test1() {
synchronized (TestSynchronized.class) {
int i = 5;
while (i-- > 0) {
System.out.println(Thread.currentThread().getName() + ":" + i);
try {
Thread.sleep(500);
} catch (InterruptedException e) {

}
}
}
}

public static synchronized  void test2() {
int i = 5;
while (i-- > 0) {
System.out.println(Thread.currentThread().getName() + ":" + i);
try {
Thread.sleep(500);
} catch (InterruptedException e) {

}
}
}

public static void main(String[] args) {
final TestSynchronized t = new TestSynchronized();
Thread test1 = new Thread(new Runnable() {

@Override
public void run() {
t.test1();
}
}, "test1");

Thread test2 = new Thread(new Runnable() {

@Override
public void run() {
t.test2();
}
}, "test2");
test1.start();
test2.start();
}
}


运行结果

test1:4
test1:3
test1:2
test1:1
test1:0
test2:4
test2:3
test2:2
test2:1
test2:0


以上两种方法都是属于类锁,因为静态方法是所有对象实例共用的,所以对应的锁也是唯一的

下面是synchronized同时修饰静态和非静态方法

public class TestSynchronized {
public void test1() {
int i = 5;
while (i-- > 0) {
System.out.println(Thread.currentThread().getName() + ":" + i);
try {
Thread.sleep(500);
} catch (InterruptedException e) {

}
}
}

public static synchronized  void test2() {
int i = 5;
while (i-- > 0) {
System.out.println(Thread.currentThread().getName() + ":" + i);
try {
Thread.sleep(500);
} catch (InterruptedException e) {

}
}
}

public static void main(String[] args) {
final TestSynchronized t = new TestSynchronized();
Thread test1 = new Thread(new Runnable() {

@Override
public void run() {
t.test1();
}
}, "test1");

Thread test2 = new Thread(new Runnable() {

@Override
public void run() {
t.test2();
}
}, "test2");
test1.start();
test2.start();
}
}


运行结果

test1:4
test2:4
test1:3
test2:3
test2:2
test1:2
test2:1
test1:1
test1:0
test2:0


交替运行,说明类锁(静态方法)和对象锁(实例方法)是不一样的锁

参考:http://zhh9106.iteye.com/blog/2151791
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: