当前位置: 首页 > 面试题库 >

同步块未锁定对象引用

丘普松
2023-03-14
问题内容
class Demo
{
    void demo()
    {
        System.out.println("Inside demo of "+Thread.currentThread().getName());
        try
        {
            Thread.sleep(1000000);
        }
        catch(InterruptedException exc)
        {
            System.out.println(Thread.currentThread().getName()+" interrupted");
        }
    }
}

class MyThread1 implements Runnable
{
    Thread thread;
    Demo d;

    MyThread1(String name, Demo ob)
    {
        d = ob;
        thread = new Thread(this, name);
        thread.start();
    }

    @Override
    public void run()
    {
        System.out.println(thread.getName()+" starting");

        synchronized(d)
        {
            d.demo();
        }

        System.out.println(thread.getName()+" ending");
    }
}

class MyThread2 implements Runnable
{
    Thread thread;
    Demo d;

    MyThread2(String name, Demo ob)
    {
        d = ob;
        thread = new Thread(this, name);
        thread.start();
    }

    @Override
    public void run()
    { 
       System.out.println(thread.getName()+" starting");

       d.demo();

       System.out.println(thread.getName()+" ending");
    }
}

class TimePass
{
    public static void main(String args[])
    {
        Demo d = new Demo();

        MyThread1 mt1 = new MyThread1("Thread 1", d);
        MyThread2 mt2 = new MyThread2("Thread 2", d);
    }
}

输出是

线程1开始

线程1的内部演示

线程2开始

线程2的内部演示

由于Thread.sleep(1000000),执行尚未结束。

我已经通过类的同一个实例Demo来的两个类的构造函数MyThread1MyThread2

Demo d = new Demo();
MyThread1 mt1 = new MyThread1("Thread 1", d);
MyThread2 mt2 = new MyThread2("Thread 2", d);

d.demoin 的调用MyThread1位于一个synchronized块中。
要在通话d.demoMyThread2没有synchronized块。

所以,当MyThread1执行时,由于synchronized块,的监视器d应锁定,导致拒绝访问,以d.demo()由所述MyThread2

但是,这没有发生。

预期的输出是

Thread 1 starting
Inside demo of Thread1
Thread 2 starting

(输出在Thread.sleep(1000000)完成之前。)

因此,我的基本问题是: 即使 尚未完成 块,
如何MyThread2.d.demo()成功执行?MyThread1.d.demo()``synchronized


问题答案:

因此,在执行MyThread1时,由于存在synchronized阻塞,的监视器d应被锁定,从而导致d.demo()MyThread2
拒绝访问。

如果MyThread2也有一个synchronized块,那只会发生。当一个线程在对象上同步时,如果其他线程也尝试在同一对象上同步,则其他线程将被阻止。如果他们不同步,它们就不会同步。没有什么可以阻止从不同步对象的线程访问对象的。

同步是一种 协作 机制。仅当所有线程一起工作时,它才起作用。



 类似资料:
  • 在示例代码中 在这个页面上, lock1和lock2分别控制c1和c2上的更新。 然而, 正在获取对象lock1的锁并在同步块时释放它 被执行。 当这个代码块被执行时,这个对象的成员c1上可能还有一个更新——我看不出这个更新是如何被代码中的lock1上的同步所阻止的。 只有对象lock1可以独占访问——除此之外别无它物(?) 那么,实施情况如何 在上面的代码中不同于 甚至 当c1是一个对象而不是一

  • 问题内容: 我正在建模一个游戏,其中多个玩家(线程)同时移动。玩家当前所在位置的信息被存储两次:该玩家具有一个变量“ hostField”,该变量引用板上的一个字段,每个字段都有一个ArrayList,用于存储当前位于该字段的玩家。 我对拥有冗余信息的事实不是很满意,但是我发现如果不遍历大数据集就无法避免这种情况。 但是,当玩家从一个字段移到另一个字段时,我想确保(1)冗余信息保持链接(2)此刻没

  • 假设我有两条线。Thread1正在访问一个同步方法,同时,Thread2正在访问同一对象的另一个同步方法。据我所知,Thread2应该等到Thread1完成它的任务。我的问题是,Thread2是否在对象的等待线程列表中?对我来说似乎是这样,但Thread2不调用wait()方法,那么作为逻辑结果,它不应该在对象的等待线程列表中。如果它不在对象的等待线程列表中,那么Thread2的状态是什么?

  • 我在学习K K 当一个方法从同步块中执行代码时,代码被称为在同步上下文中执行。当您同步一个方法时,用于调用该方法的对象是必须获取其锁的对象。但是当我们同步代码块时,您必须指定要使用哪个对象的锁作为锁。 在本例中,会在AccountDanger实例或Account对象上获取锁吗?我想应该是这样的。我感觉正确吗?如果它是AccountDanger对象,并且一个线程已获得AccountDanger锁,那

  • 问题内容: 我想要一个布尔值来通知系统的某些部分特定服务已启动。 由于某些奇怪的原因,我得到了错误。 奇怪的是notifyAll()在一个同步块内,该块控制着我调用notifyAll()的对象。 我的课是这样开始的: 我正在开发一个android应用程序。我认为它不会影响任何事情,但是我会在注释中补充这个问题,以防影响Java的工作方式。 如果对象锁定在同步块中,为什么会出现异常? 问题答案: 线

  • 尝试可视化和理解同步。 对同步块使用静态锁定对象(代码a)和非静态锁定对象(代码B)之间有什么区别 它在实际应用中有什么不同 一方会有哪些陷阱而另一方不会 确定使用哪一个的标准是什么 代码A 代码B 笔记 上面的代码显示了构造函数,但是您可以讨论静态方法和非静态方法中的行为是如何不同的。另外,在同步块修改静态成员变量时使用静态锁是否有利? 我已经看过了这个问题的答案,但是还不清楚不同的使用场景是什