Java的synchronized锁机制
| synchronized (this) | 加synchronized的方法 |
---|
两个线程访问该类同一个方法 | 该对象加锁的需等待,不加锁不等待 | 加锁的需等待,不加锁不等待 |
两个线程访问该类不同的方法 | 该对象加锁的方法需等待,不加锁不等待 | 加锁的同是静态和非静态时等待,不同时不等待;不加锁的不等待 |
类锁-静态方法锁和非静态方法锁的示例
package com.test.sych;
/**测试类级别锁,如果锁只是加在非静态方法名称上,这个锁是在方法级别,只有同时进入该静态或非静态方法时则会互相有影响, 方法之间不影响。如果锁是加在静态方法上,则可以理解为类锁,那么该类的其他sychronized静态方法之间都有影响
* 下面的代码输出结果是交叉执行的,互不影响:
* testA : 2
testB : 2
testA : 1
testB : 1
testA : 0
testB : 0
* 但如果两个线程访问的是同一个方法,则会出现等待synchronized方法执行完毕.
* @author royli
*
*/
public class TestClassSynchronized {
public synchronized void test1() {
int i =3;
while (i-- >0) {
System.out.println(Thread.currentThread().getName() +" : " + i);
try {
Thread.sleep(500);
}catch (InterruptedException ie) {
}
}
}
public static synchronized void test2() {
int i =3;
while (i-- >0) {
System.out.println(Thread.currentThread().getName() +" : " + i);
try {
Thread.sleep(500);
}catch (InterruptedException ie) {
}
}
}
public static void main(String[] args) {
final TestClassSynchronized myt2 =new TestClassSynchronized();
Thread test1 =new Thread(new Runnable() {
public void run() {
myt2.test1();
}
},"testA");
Thread test2 =new Thread(new Runnable() {
public void run() {
TestClassSynchronized.test2();
// myt2.test1();
}
},"testB");
test1.start();
test2.start();
}
}
对象锁的示例
package com.test.sych;
/**演示对象锁的作用,锁住this也即使锁住了当前对象,调用test1和test2方法,因为二个方法都是synchronized方法,那么两个线程都需要获得该对象锁,另一个线程必须等待。
* 输出结果如下:
* testA : 2
testA : 1
testA : 0
testB : 2
testB : 1
testB : 0
* 如果test2不带有synchronized标注,即使对象加锁,则test2方法与test1不会争抢资源并等待
* @author royli
*
*/
public class TestSynchronized {
public void test1() {
synchronized (this) {
int i =3;
while (i-- >0) {
System.out.println(Thread.currentThread().getName() +" : " + i);
try {
Thread.sleep(500);
}catch (InterruptedException ie) {
}
}
}
}
public synchronized void test2() {
int i =3;
while (i-- >0) {
System.out.println(Thread.currentThread().getName() +" : " + i);
try {
Thread.sleep(500);
}catch (InterruptedException ie) {
}
}
}
public static void main(String[] args) {
final TestSynchronized myt2 =new TestSynchronized();
Thread test1 =new Thread(new Runnable() {
public void run() {
myt2.test1();
}
},"testA");
Thread test2 =new Thread(new Runnable() {
public void run() {
myt2.test2();
}
},"testB");
test1.start();
test2.start();
}
}