1. Java中加同步锁目前使用synchronized
锁目前可以理解为下面两种锁,然后每种锁都可以加在代码上或者方法上(也可以按照方法锁和代码锁分类)
第一种分类:
1)类锁
A : 只加在某块代码中,但是加锁的是类 synchronized(Sync.class)
b: 加在静态方法上:
public static synchronizedvoid test1() {...}
2)对象锁
A: 加在某块代码中,但是加锁的是对象
synchronized (this)
B: 加在非静态方法上
public synchronized void test() {...}
第二种分类
1) 方法锁
A: 方法锁锁在非静态方法:即锁在对象
public synchronized void test() {...}
B: 方法锁锁在静态方法上: 即锁在类上
public static synchronized void test1() {...}
2) 代码锁
A:加锁的是类 synchronized(Sync.class)
B: 加在某块代码中,但是加锁的是对象
synchronized (this)
注意
1)类锁和对象锁不会互斥,不能理解为锁加在类上, 由这个类产生的对象就获取不到锁
2)类锁和类锁互斥,对象锁和同一对象的锁互斥,类锁和对象锁互不排斥,不同对象的锁不互斥
2. 举例
package com.yaya.java.sync;
public class Sync1 {
public void test() {
synchronized (Sync1.class) {
System.out.println("synchronized Sync1.class 开始..");
try {
Thread.sleep(2000);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("synchronized Sync1.class 结束..");
}
}
public static synchronized void test1() {
System.out.println("static synchronized void test1 开始..");
try {
Thread.sleep(2000);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("static synchronized void test1结束..");
}
public static void main(String[] args) {
Sync1 test1 = new Sync1();
Thread thread = new Thread(new Runnable() {
public void run() {
test1.test();
}
}, "a");
Thread thread1 = new Thread(new Runnable() {
public void run() {
Sync1.test1();
}
}, "b");
thread1.start();
thread.start();
}
}
运行结果
static synchronized void test1 开始..
static synchronized void test1结束..
synchronized Sync1.class 开始..
synchronized Sync1.class 结束..
分析:
synchronized (Sync1. class ) 锁在类Sync1上,
public static synchronizedvoid test1() 也锁在Sync1类上, 所以两个方法互斥。
package com.yaya.java.sync;
public class Sync2 {
public void test() {
synchronized (Sync2.class) {
System.out.println("synchronized (Sync2.class)开始..");
try {
Thread.sleep(2000);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("synchronized (Sync2.class)结束..");
}
}
public void test2() {
synchronized (this) {
System.out.println("synchronized (this)开始..");
try {
Thread.sleep(2000);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("synchronized (this)结束..");
}
}
public static void main(String[] args)
{
Sync2 test1 = new Sync2();
Thread thread = new Thread(new Runnable()
{
public void run()
{
test1.test();
}
}, "a");
Sync2 test2 = new Sync2();
Thread thread2 = new Thread(new Runnable()
{
public void run()
{
test2.test2();
}
}, "a");
thread.start();
thread2.start();
}
}
运行结果
synchronized (this)开始..
synchronized (Sync2.class)开始..
synchronized (this)结束..
synchronized (Sync2.class)结束..
分析:
类锁和对象锁不互斥
package com.yaya.java.sync;
public class Sync3 {
public synchronized void test() {
System.out.println("test开始..");
try {
Thread.sleep(2000);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("test结束..");
}
public synchronized void test2() {
System.out.println("test2开始..");
try {
Thread.sleep(2000);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("test2结束..");
}
public static void main(String[] args) {
Sync3 test1 = new Sync3();
Thread thread = new Thread(new Runnable() {
public void run() {
test1.test();
}
}, "a");
Thread thread2 = new Thread(new Runnable() {
public void run() {
test1.test2();
}
}, "c");
Sync3 test2 = new Sync3();
Thread thread3 = new Thread(new Runnable() {
public void run() {
test2.test2();
}
}, "a");
thread.start();
thread2.start();
thread3.start();
}
}
运行结果:
test2开始..
test2开始..
test2结束..
test2结束..
test开始..
test结束..
分析:
对象锁,锁同一个对象,会互斥(thread thread2互斥),但是锁的不是同一个对象(thread2 thread3不互斥)
public class Sync4 {
/**
* 加锁方法调用加锁方法
*/
private synchronized void testA() {
System.out.println("testA start");
testB();
try {
Thread.sleep(2000);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("testA over");
}
private synchronized void testB() {
System.out.println("testB start");
try {
Thread.sleep(2000);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("testB over");
}
public static void main(String[] args) {
Sync4 syn4 = new Sync4();
syn4.testA();
}
}
运行结果:
testA start
testB start
testB over
testA over
分析:
testA获得了对象锁,虽然testB也需要对象锁,但是运行在testA中, 所以testB也能获得对象锁。