如果一个代码块被synchronized关键字修饰,当一个线程获取了对应的锁,并执行该代码块时,其他线程便只能一直等待直至占有锁的线程释放锁。事实上,占有锁的线程释放锁一般会是以下三种情况之一:
1:占有锁的线程执行完了该代码块,然后释放对锁的占有;
2:占有锁线程执行发生异常,此时JVM会让线程自动释放锁;
3:占有锁线程进入 WAITING 状态从而释放锁,例如在该线程中调用wait()方法等
Synchronized修饰静态变量和普通变量的区别
这里主要涉及到类对象(static方法),对象方法(非static方法)
我们知道,当synchronized修饰一个static方法时,多线程下,获取的是类锁(即Class本身,注意:不是实例);
当synchronized修饰一个非static方法时,多线程下,获取的是对象锁(即类的实例对象)
public class TestSyn {
private Integer a = 0;
private Integer b = 0;
public static void main(String args[]){
TestSyn tt=new TestSyn();
tt.A();
tt.B();
}
public synchronized void A() {
new Thread(new Runnable() {
@Override
public void run() {
System.out.println("A线程准备");
{
System.out.println("A线程开始");
for (int i = 0; i < 10; i++) {
System.out.println("a" + i);
try {
Thread.sleep(500);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
}).start();
}
public synchronized void B() {
new Thread(new Runnable() {
@Override
public void run() {
System.out.println("B线程准备");
{
System.out.println("B线程开始");
for (int i = 0; i < 10; i++) {
System.out.println("b" + i);
try {
Thread.sleep(500);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
}).start();
}
}
以上是交叉打印
A线程准备
A线程开始
a0
B线程准备
B线程开始
b0
a1
b1
a2
b2
a3
b3
a4
b4
a5
b5
a6
b6
a7
b7
a8
b8
a9
b9
交叉的原因是线程等待了,释放了锁。
如果不等待呢?
答案:那么则按照顺序执行。