请热心大佬帮看下,我在看相关文章时,测试敲一下相关代码,发现 synchronized 代码块 的三种情况(其实还有一种成员变量 一会在试下),发现有
//synchronized ( 当前类.class) {
//synchronized (当前类中定义类变量的类.class) {
//synchronized (当前类中定义类变量的类引用) {
//synchronized (其他用不到的类.class)(解释:就是导进来就可以用了实际功能代码用不上,比如下面的 synchronized (MyImpl.class) )
//synchronized (应该还有成员变量的类引用,不过这个还没试)
请帮解惑其中区别原理,目前发现 示例中 synchronized (digitCard) 就是上面第三种,看结果是保证了线程同步执行,但是看打印语句,又似乎每个线程还未执行完,就释放锁,执行其他线程,然后又回来哈哈😂,但是最终结果是对的,就是还是保证了原子性,难道是jvm自己排序了,导致打印错乱了,实际上运行时正确的?
(结果如下图,如果不明白,请最好在本地跑一下 。)
synchronized (DigitCard.class) 结果:
//synchronized (synchronizedTest.class) 结果:
//synchronized (MyImpl.class) 结果:
按道理使用了synchronized ,应该会 按照 10 20 30...这个顺序打印,只是线程不一定哪个先执行,并且打印不会出现错乱哈
上面 三个,都可以做到同一个线程的俩个打印语句先后一起打印出来
T-0----begin 0
DigitCard{account 'zhangsan', amount=10-----T-0
T-2----begin 10
DigitCard{account 'zhangsan', amount=20-----T-2
T-3----begin 20
DigitCard{account 'zhangsan', amount=30-----T-3
T-7----begin 30
DigitCard{account 'zhangsan', amount=40-----T-7
T-5----begin 40
DigitCard{account 'zhangsan', amount=50-----T-5
T-6----begin 50
DigitCard{account 'zhangsan', amount=60-----T-6
T-8----begin 60
DigitCard{account 'zhangsan', amount=70-----T-8
T-1----begin 70
DigitCard{account 'zhangsan', amount=80-----T-1
T-4----begin 80
DigitCard{account 'zhangsan', amount=90-----T-4
T-9----begin 90
DigitCard{account 'zhangsan', amount=100-----T-9
synchronized (DigitCard) 结果:
T-0----begin 0
DigitCard{account 'zhangsan', amount=10-----T-0
T-3----begin 10
T-4----begin 10
DigitCard{account 'zhangsan', amount=20-----T-3
T-5----begin 30
T-2----begin 30
DigitCard{account 'zhangsan', amount=50-----T-2
DigitCard{account 'zhangsan', amount=30-----T-4
T-1----begin 50
T-6----begin 50
DigitCard{account 'zhangsan', amount=70-----T-6
DigitCard{account 'zhangsan', amount=40-----T-5
T-8----begin 70
DigitCard{account 'zhangsan', amount=60-----T-1
T-9----begin 80
DigitCard{account 'zhangsan', amount=80-----T-8
DigitCard{account 'zhangsan', amount=90-----T-9
T-7----begin 90
DigitCard{account 'zhangsan', amount=100-----T-7
class DigitCard {
private final String name;
private final int account;
public DigitCard(String name,int account) {
this.name = "zhangsan";
this.account = account;
}
public String getName() {
return name;
}
public int getAccount() {
return account;
}
@Override
public String toString() {
return "DigitCard{account 'zhangsan', amount="+account;
}
}
public class synchronizedTest{
static DigitCard digitCard =new DigitCard("zhangsan",0);
public static void main(String[] args) {
for(int i=0;i<10;i++) {
new Thread("T-"+i) {
@Override
public void run() {
// try {
// Thread.sleep(1000);
// } catch (InterruptedException e) {
// // TODO Auto-generated catch block
// e.printStackTrace();
// }
//这里有大佬可以讲解下四者的区别吗 感谢
//synchronized (MyImpl.class) {
//synchronized (synchronizedTest.class) {
//synchronized (DigitCard.class) {
synchronized (digitCard) {
System.out.println(Thread.currentThread().getName()+"----begin " +digitCard.getAccount());
DigitCard dc=digitCard;
DigitCard newDigitCard =new DigitCard("zhangsan",dc.getAccount()+10);
digitCard=newDigitCard;
System.out.println(newDigitCard+"-----"+Thread.currentThread().getName());
}
}
}.start();
}
}
}