Significance of use of keyword synchronized in the following code

huangapple go评论71阅读模式
英文:

Significance of use of keyword synchronized in the following code

问题

以下是您要翻译的内容:

我正在从Herbert Schildt的书《Java完全参考》1中阅读有关Java中的多线程。我遇到了以下代码*[第252页,第7版]*,该代码解释了在现代Java中使用wait()notify()来挂起和恢复线程的用法。我的问题与以下代码中的两个地方的关键字synchronization的重要性有关(在NewThread类的run()方法中):

// 以现代方式挂起和恢复线程。
class NewThread implements Runnable {
	String name;
	Thread t;
	boolean suspendFlag;
	NewThread(String threadname) {
		name = threadname;
		t = new Thread(this, name);
		suspendFlag = false;
		t.start();
	}
// 这是线程的入口点。
	public void run() {
		try {
			for (int i = 15; i > 0; i--) {
				System.out.println(name + ": " + i);
				Thread.sleep(200);
				synchronized (this) { // 这里是第一个疑问
					while (suspendFlag) {
						wait();
					}
				}
			}
		} catch (InterruptedException e) {
			System.out.println(name + " interrupted.");
		}
		System.out.println(name + " exiting.");
	}
	void mysuspend() {
		suspendFlag = true;
	}
	synchronized void myresume() { // 这里是第二个疑问
		suspendFlag = false;
		notify();
	}
}

class SuspendResume {
	public static void main(String args[]) {
		NewThread ob1 = new NewThread("One");
		NewThread ob2 = new NewThread("Two");
		try {
			Thread.sleep(1000);
			ob1.mysuspend();
			Thread.sleep(1000);
			ob1.myresume();
			ob2.mysuspend();
			Thread.sleep(1000);
			ob2.myresume();
		} catch (InterruptedException e) {
			System.out.println("Main thread Interrupted");
		}
        // 一些代码
}

我的疑问:我知道关键字synchronization的用途,即只允许一个线程在同一个对象上进入同步方法,但在这里我们有两个线程在两个不同的对象上运行。因此,以上代码中使用的两个synchronization关键字的重要性是什么。

我尝试删除不同位置的Synchronization关键字并同时运行以上代码。我得到了相同的错误:java.lang.IllegalMonitorStateException: current thread is not owner,错误次数和行数不同,具体取决于我是否删除了两个关键字中的哪一个以及删除哪一个。我查找了上述错误,并在这里找到了一个解释,但仍然无法与我的疑问联系起来。

英文:

I was reading multi threading in Java from the book Java The Complete Reference by Herbert Schildt. I came across following code [Pg. 252, 7th ed.] that explained the usage of wait() and notify() to suspend and resume threads in modern Java. My question is regarding the significance of the keyword synchronization at two places in following code (in run() method of class NewThread):

// Suspending and resuming a thread the modern way.
class NewThread implements Runnable {
	String name;
	Thread t;
	boolean suspendFlag;
	NewThread(String threadname) {
		name = threadname;
		t = new Thread(this, name);
		suspendFlag = false;
		t.start();
	}
// 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);
				synchronized (this) { //First doubt here
					while (suspendFlag) {
						wait();
					}
				}
			}
		} catch (InterruptedException e) {
			System.out.println(name + " interrupted.");
		}
		System.out.println(name + " exiting.");
	}
	void mysuspend() {
		suspendFlag = true;
	}
	synchronized void myresume() { //Second doubt here
		suspendFlag = false;
		notify();
	}
}

class SuspendResume {
	public static void main(String args[]) {
		NewThread ob1 = new NewThread("One");
		NewThread ob2 = new NewThread("Two");
		try {
			Thread.sleep(1000);
			ob1.mysuspend();
			Thread.sleep(1000);
			ob1.myresume();
			ob2.mysuspend();
			Thread.sleep(1000);
			ob2.myresume();
		} catch (InterruptedException e) {
			System.out.println("Main thread Interrupted");
		}
        //some code
}

My doubt here: I know about the use of keyword synchronization i.e. allowing only one thread to enter a synchronized method on the same object but here we have two threads running on two different objects. So what is the significance of both synchronization keywords used in above code.

I tried running the above code by removing the synchronized keyword at each place differently and simultaneously. I am getting the same error: java.lang.IllegalMonitorStateException: current thread is not owner different number of times and at different line numbers depending upon if I remove both or only one (and which one) synchronization keyword. I looked for the above error and found an explanation for it here but still couldn't connect the answer to my doubt.

答案1

得分: 0

synchronized 解决的问题是它允许两个线程对共享的 suspendFlag 变量有一致的视图。

在一些实际程序中,一个线程可能在将 susependFlag=false 设置之前设置其他共享变量。如果没有使用 synchronized,那么等待的线程可能会唤醒,并且看到 suspendFlag==false,但是不会看到其他变量被设置。或者更糟糕的是,它可能看到其中一些被设置,但其他的没有。

在没有同步的情况下,Java 不保证不同的线程会以相同的顺序看到变量的更新。

我得到了相同的错误:java.lang.IllegalMonitorStateException: 当前线程不是所有者。

Java 库试图通过 强制 你在允许使用 wait()notify() 之前使用 synchronized 来帮助你。规则很简单:只有在位于 synchronized(o) 块内的代码中才能调用 o.wait()o.notify()o.notifyAll()。如果你违反这个规则,那么库会抛出异常。

当你的代码调用 o.wait() 时,wait() 调用会临时 解锁 监视器锁,以便其他线程能够对 o 进行同步并调用 o.notify()o.wait() 调用保证在返回之前重新锁定 o

英文:

The problem that synchronized solves is, it allows the two threads to have a consistent view of the shared suspendFlag variable.

In some real program, a thread might set other shared variables before setting susependFlag=false. If synchronized was not used, then the waiting thread could wake up, and see suspendFlag==false, but not see the other variables set. Or worse, it could see some of them set, but not others.

Without synchronization, Java does not guarantee that different threads will see variables updated in the same order.

> I am getting the same error: java.lang.IllegalMonitorStateException: current thread is not owner.

The Java library is trying to help you by forcing you to use synchronized before it will allow you to use wait() and notify(). The rule is simple: You can only call o.wait() or o.notify() or o.notifyAll() from code that is inside a synchronized(o) block. If you break that rule, then the library throws the exception.

When your code calls o.wait() the wait() call temporarily unlocks the monitor lock so that the other thread will be able to synchronize on o and call o.notify(). The o.wait() call is guaranteed to re-lock o before it returns.

huangapple
  • 本文由 发表于 2020年8月6日 01:30:27
  • 转载请务必保留本文链接:https://go.coder-hub.com/63270527.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定