代码之家  ›  专栏  ›  技术社区  ›  bragboy

关于Java多线程的一个问题

  •  6
  • bragboy  · 技术社区  · 14 年前

    假设以下类

    public class TestObject{
        public void synchronized method1(){
            //some 1000 lines of code
        }
    
        public void method2(){
            //some 1000 lines of code
        }
    }
    

    1. 当t1在访问method1()的中途时。现在t2正在尝试访问method2()。

    我的理解是,对于第一个问题,线程t2不会作为 对象

    谢谢

    6 回复  |  直到 14 年前
        1
  •  4
  •   Cameron Skinner    14 年前

    当您声明要同步的方法时,例如:

    public synchronized void foo() {
        // Do something
    }
    

    编译器将其视为您编写的:

    public void foo() {
        synchronized (this) {
            // Do something
        }
    }
    

    method1 将被锁定。锁定检查仅在进入 synchronized 布洛克,这么叫 method2 不会触发任何锁定。

    方法2 要同步(或手动添加 synchronized (this)

    记住:同步对象不会阻止其他线程调用该对象上的方法。它只防止另一个线程使用同一个锁对象进入同步块。

    顺便说一下,通常最好有一个内部锁对象,而不是声明要同步的方法,例如。

    class Foo {
        private final Object LOCK = new Object();
        public void doSomething() {
            synchronized (LOCK) {
                // Whatever
            }
        }
    }
    

    class MessEverythingUp {
        public MessEverythingUp(Foo foo) {
            synchronized (foo) {
                while (true) {
                    System.out.println("Pwnd ur thread safety");
                }
            }
        }
    }
    

    因为我锁定了foo的实例,所以同步的方法(带有它们的隐式“synchronized(this)”)将无法获得锁,并将永远阻塞。最重要的是,你不能阻止这一点,因为我可以在任何我喜欢的对象上同步。很明显,这个例子是极端的,但是如果你对这类事情不小心的话,你可能会得到讨厌的,微妙的死锁错误。

        2
  •  8
  •   Cratylus    14 年前

    只有关键字为synchronized的方法持有 当线程在该方法中运行时。
    如果方法1和方法2都声明为已同步,则一个线程将阻塞另一个线程,即使它们试图运行不同的方法。
    在您的示例中,只有1个方法被隐式锁阻塞。
    结果,t1和t2可以在方法1和方法2中同时运行(反之亦然)。
    只有在尝试访问方法1时,如果已经获取锁,t1或t2才会阻塞

        3
  •  3
  •   Erick Robertson InsertNickHere    14 年前

    在这两种情况下,第二个线程都将被授予执行其方法的权限。

    因为这两个方法中只有一个包含 synchronized

    在这里我还假设 method2 不包含这样的块:

    synchronized (this) {
    }
    

    如果是这样的话,结果就不一样了。

    1. t2将被允许开始执行该方法。当它击中 同步的 method1 在继续之前释放锁。
    2. 只要t1不在 同步的 同步的
        4
  •  2
  •   MAK    14 年前

    一个方法是同步的,而另一个不是。因此,无论对象上的锁(在本例中是方法所属的实例)是否已被获取,非同步方法都将不受阻碍地执行(因为它不试图获取或等待锁)。这意味着在这两种情况下,两个线程都将在不等待对方的情况下运行,这可能导致对象的状态不一致。

        5
  •  0
  •   Tushar Joshi    14 年前

    method1()是同步的,因此称为线程安全方法。当多个线程试图同时访问此方法时,只有实例对象上的锁才能工作。

    在这两种情况下,您提到的一个线程将通过调用method1()获得实例的锁,另一个线程将尝试访问method2(),这是不安全的,因此两个线程都将执行。


    那格浦尔图沙尔乔希

        6
  •  0
  •   josefx    14 年前

    两个线程都将像不存在锁一样执行。

    如果两个线程都执行method1,其中一个线程将阻塞,直到另一个线程退出该方法并释放锁为止。

    要确保只有一个线程执行,所有其他线程等待,必须使两个方法同步。