与volatile不同的是 synchronized不能对变量使用
目录
对于同步方法块。锁是Synchronized括号里配置的对象。
虽然说synchronized不能直接对变量使用,但是可以对调用他的方法的上锁,从而实现对其上锁
对于普通方法锁是当前对象
例:
public class Person {
private int f = 0;
public synchronized void m1(String x){
System.out.println(x+"执行加锁普通m1");
try {
Thread.sleep(3000);
}catch (InterruptedException e){
e.printStackTrace();
}
System.out.println(x+"执行结束加锁普通m1");
}
public void m2(String x){
System.out.println(x+"执行无锁普通m2");
try {
Thread.sleep(3000);
}catch (InterruptedException e){
e.printStackTrace();
}
System.out.println(x+"执行无锁普通m2结束");
}
public synchronized void m3(String x){
System.out.println(x+"执行加锁普通m3");
try {
Thread.sleep(3000);
}catch (InterruptedException e){
e.printStackTrace();
}
System.out.println(x+"执行结束加锁普通m3");
}
}
main方法
public static void main(String[] args) {
Person p1 = new Person();
Thread t1 = new Thread() {
@Override
public void run() {
p1.m1("线程t1");
}
};
Thread t2 = new Thread() {
@Override
public void run() {
p1.m2("线程t2");
p1.m3("线程t2");
}
};
t1.start();
t2.start();
}
结果
首先可以看出线程t1执行后,立马执行无锁的t2,说明虽然对对象方法上锁等于锁住实例对象但是对于无锁方法来说无效,只是锁有锁的方法。m2方法立即执行完毕。然后等待三秒,等待完成m1的执行,对p1解锁才让m3执行这也证明了,对于普通方法锁是当前对象
对于静态同步法,锁是当前类的Class对象。
首先可以 看出仍然对无锁的普通的m2无影响,m3同样等了m1执行结束,释放Person类的锁,m3才执行
接着将m2换成静态可见结果仍一样
对于同步方法块。锁是Synchronized括号里配置的对象。
public static void main(String[] args) {
Integer A=0;
Thread t1 = new Thread() {
@Override
public void run() {
synchronized(A){
try {
System.out.println("线程t1打印"+(A));
Thread.sleep(3000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
System.out.println("代码块执行完毕,释放锁");
try {
Thread.sleep(1000);
System.out.println("t1才刚刚执行完,没想到吧");
} catch (InterruptedException e) {
e.printStackTrace();
}
}
};
Thread t2 = new Thread() {
@Override
public void run() {
synchronized(A){
System.out.println("线程t2打印"+A);
}
}
};
t1.start();
t2.start();
}
看执行结果
同样是t1对A上锁,在代码块执行完了,t2就开始对A操作,t2打印完,过一段时间才执行完t1,所以很明显,锁只在块内对A限制