Java 了解同步关键字的工作原理

Java 了解同步关键字的工作原理,java,synchronized,Java,Synchronized,在下面的代码中,我只希望两个线程中的一个进入halt函数,然后停止程序。但这两个线程似乎都进入了synchronized halt函数。为什么会发生这种情况 package practice; class NewThread implements Runnable { String name; // name of thread Thread t; boolean suspendFlag; NewThread(String threadname) { name = t

在下面的代码中,我只希望两个线程中的一个进入halt函数,然后停止程序。但这两个线程似乎都进入了synchronized halt函数。为什么会发生这种情况

package practice;

class NewThread implements Runnable {
  String name; // name of thread
  Thread t;
  boolean suspendFlag;

  NewThread(String threadname) {
    name = threadname;
    t = new Thread(this, name);
    System.out.println("New thread: " + t);
    suspendFlag = false;
    t.start(); // Start the thread
  }

  // This is the entry point for thread.
  public void run() {
    try {
      for(int i = 15; i > 0; i--) {
        System.out.println(name + ": " + i);
        Thread.sleep(200);
        Runtime r = Runtime.getRuntime();
        halt();
      }
    } catch (InterruptedException e) {
      System.out.println(name + " interrupted.");
    }
    System.out.println(name + " exiting.");
  }

  synchronized void halt() throws InterruptedException
  {
      System.out.println(name + " entered synchronized halt");
      Runtime r = Runtime.getRuntime();
      Thread.sleep(1000);
      r.halt(9);
      System.out.println(name + " exiting synchronized halt"); // This should never execute
  }
}

class Practice{
  public static void main(String args[]) {
    NewThread ob1 = new NewThread("One");
    NewThread ob2 = new NewThread("Two");

    // wait for threads to finish
    try {
      System.out.println("Waiting for threads to finish.");
      ob1.t.join();
      ob2.t.join();
    } catch (InterruptedException e) {
      System.out.println("Main thread Interrupted");
    }

    System.out.println("Main thread exiting."); // This should never execute
  }
}

synchronized不会锁定方法,而是锁定对象


您有一个方法,但有两个对象。每个线程都锁定自己的对象并调用halt。

同步不会锁定方法,而是锁定对象


您有一个方法,但有两个对象。每个线程都锁定自己的对象并调用halt。

同步在每个对象上完成。如果您有两个对象,那么两个线程可能同时进入halt方法。您可以将该方法设置为静态,以实现所需的功能。通过使其为静态,锁将被放在相应的类对象NewThreadOne.Class上,该对象对于NewThreadOne的实例数是唯一的

同步在每个对象上完成。如果您有两个对象,那么两个线程可能同时进入halt方法。您可以将该方法设置为静态,以实现所需的功能。通过使其为静态,锁将被放在相应的类对象NewThreadOne.Class上,该对象对于NewThreadOne的实例数是唯一的

您已将两个线程的两个对象用作其监视器锁

因此,您的代码工作正常,每个线程都访问自己对象的锁以访问halt方法

在synchonized关键字中,您实现了一个对象的锁定,通过该锁定,线程可以访问该类中的同步方法或原子语句……

您已经使用了两个线程的两个对象作为其监视器锁定

因此,您的代码工作正常,每个线程都访问自己对象的锁以访问halt方法


在synchonized关键字中,您实现了对象的锁定,通过该锁定,线程可以访问该类中的同步方法或原子语句……

同步方法使用该锁定。在本例中,您有两个不同的对象,因为您正在构建两个线程实例,所以您没有锁定同一个对象。为了获得预期的同步行为,需要将halt方法设置为静态。

同步方法使用此方法进行锁定。在本例中,您有两个不同的对象,因为您正在构建两个线程实例,所以您没有锁定同一个对象。为了获得预期的同步行为,需要将halt方法设置为静态。

不建议在java同步块中使用字符串对象作为锁,因为字符串是不可变的对象,而文本字符串和内部字符串存储在字符串池中。因此,如果代码的任何其他部分或任何第三方库使用了与锁相同的字符串,那么它们都将被锁定在同一个对象上,尽管它们完全不相关,这可能会导致意外的行为和糟糕的性能。建议在Java同步块上使用新对象进行同步,而不是字符串对象。

不建议在Java同步块中使用字符串对象作为锁,因为字符串是不可变对象,文本字符串和插入字符串存储在字符串池中。因此,如果代码的任何其他部分或任何第三方库使用了与锁相同的字符串,那么它们都将被锁定在同一个对象上,尽管它们完全不相关,这可能会导致意外的行为和糟糕的性能。建议在Java的同步块上使用新对象进行同步,而不是字符串对象。

这两个对象不是独立的吗?如果我正确理解了你的代码,每个线程都在自己的对象上执行。这两个对象不是分开的吗?如果我正确理解了您的代码,每个线程都会在自己的对象上执行。