为了账号安全,请及时绑定邮箱和手机立即绑定

同一个方法中的被synchronized包裹的代码块与普通代码块

public class SynchronizedCodeblock implements Runnable{
static SynchronizedCodeblock instance1 = new SynchronizedCodeblock();
//static SynchronizedCodeblock instance2 = new SynchronizedCodeblock();
static int i = 0;
public static void main(String[] args) {
Thread t1 = new Thread(instance1);
Thread t2 = new Thread(instance1);
t1.start();
t2.start();
while(t1.isAlive() || t2.isAlive() ) {}
System.err.println(i);
System.err.println("finished!");
}
public void run() {
method();
}
public void method() {
//synchronized(SynchronizedCodeblock.class) {
synchronized(this) {
System.err.println("我是同步块内代码,我叫:"+Thread.currentThread().getName());
for (int j = 0; j < 10000; j++)
        {
System.err.println(Thread.currentThread().getName() +": " + i++);
        }
System.err.println("同步块内代码运行结束,我叫:"+Thread.currentThread().getName());
}
System.err.println("我是同步块外代码,我叫:"+Thread.currentThread().getName());
for (int j = 0; j < 100000; j++)
        {
System.err.println(Thread.currentThread().getName() +": " + i++);
        }
System.err.println("同步块外代码运行结束,我叫:"+Thread.currentThread().getName());
}
}


结果:

。。。

Thread-1: 219984

Thread-1: 219985

Thread-1: 219986

同步块外代码运行结束,我叫:Thread-1

219987

finished!


我不太明白,当某个线程执行到ssynchronized代码块发现拿不到锁时,该线程会跳过这端代码,然后执行下面的代码吗,如果是这样,我就不理解了,这两块代码都在一个线程,为什么不会顺序执行呢,jvm做了什么,迷惑,求教?


正在回答

2 回答

每个对象都有一个请求头,请求头里面不仅有当前锁被哪个线程获取的状态标识,也有锁的类型,是轻量级,重量,可偏向,等有阻塞队列, 这就像是juc包里面aqs的实现用chl。 就是说,两个线程获取一把锁,一个线程拿到了,另一个线程的状态就会变成block阻塞,阻塞了就不受cpu机制的控制了,只有等拿到锁的线程释放了锁,这个block的线程才会变成就绪状态,等待cpu分配,去竞争这个锁。

0 回复 有任何疑惑可以回复我~

我对jvm不太了解,但用Linux中的给你解释下。
当一个线程想去获取一把锁而获取不到时,是处在一个死循环状态。

while( 没有得到锁)
{
     尝试获取锁;
}

所以就相当于死在了这个循环里面。

当然还有尝试锁,先尝试获取,没获取到就退出,而不是死在循环中。

锁的内容还有很多,慢慢学吧。

1 回复 有任何疑惑可以回复我~

举报

0/150
提交
取消

同一个方法中的被synchronized包裹的代码块与普通代码块

我要回答 关注问题
意见反馈 帮助中心 APP下载
官方微信