不同对象上的同步语句可以交错吗?

问题描述 投票:0回答:2

我正在研究关键字synchronized,但我不知道是否可以在同一类中插入2个同步语句;例如:

我使用这些简单的方法和两个锁定对象制作了一个类:

public class Locker1 {  
    private Object lock1= new Object();
    private Object lock2= new Object();

    public void printL1() {
        synchronized(lock1) {
            for(int i=0; i<50;i++) {
                System.out.println(i);
            }
        }
    }

    public void printL2() {
        synchronized(lock2) {
            for(int i=0; i<50;i++) {
                System.out.println("-"+i);
            }
        }
    }
}

我制作了两个仅调用printL1printL2的不同线程,据我所知,我认为由于这是两个不同的锁,我会看到交替打印正数和负数,因为可以并发,但是我尝试了多次,并且[ C0]总是完全发生在printL2之后,不是一次我看到正数之间的负数,就是同步时丢失了什么吗?

这里是其余代码

printL1
public class ThreadA extends Thread {
    private Locker1 l1;

    public ThreadA(Locker1 l1) {
        this.l1=l1;
    }

    public void run() {
        l1.printL1();
    }
}

和主要班级:

public class ThreadB extends Thread {   
    private Locker1 l1;

    public ThreadB(Locker1 l1) {
        this.l1=l1;
    }

    public void run() {
        l1.printL2();
    }   
}
java locking synchronized
2个回答
0
投票

交错发生预期;仅进行了50次迭代就很难看到,因此多进行多次迭代就可以看到它


0
投票

您对线程和锁的理解是正确的。由于public class Main { public static void main(String[] args) { Locker1 l1=new Locker1(); ThreadA tA=new ThreadA(l1); ThreadB tB=new ThreadB(l1); tA.start(); tB.start(); } } Locker1.printL1()将锁授予不同的对象,因此一个线程访问Locker1.printL2()而另一个访问Locker1.printL1()不应互相阻塞。

之所以在printL1之后看到完整的printL2结果,是因为该工作对CPU而言太少了。 50次迭代需要几分之一毫秒才能完成。在需要Locker1.printL2()之前,任务已完成。

让任务休眠一小段时间,您就可以看到线程的产量。

context switch

输出:

public class Locker1 {
    private Object lock1 = new Object();
    private Object lock2 = new Object();

    public void printL1() {
        synchronized (lock1) {
            for (int i = 0; i < 50; i++) {
                System.out.println(i);
                try {
                    Thread.sleep(50);
                } catch (InterruptedException e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                }
            }
        }
    }

    public void printL2() {
        synchronized (lock2) {
            for (int i = 0; i < 50; i++) {
                System.out.println("-" + i);
                try {
                    Thread.sleep(50);
                } catch (InterruptedException e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                }
            }
        }
    }
}
© www.soinside.com 2019 - 2024. All rights reserved.