gpt4 book ai didi

java - 如何使线程 - notify()/notifyAll() 私有(private)

转载 作者:行者123 更新时间:2023-12-02 04:46:04 25 4
gpt4 key购买 nike

有办法阻止线程调用 notify()/notifyAll() 吗?然后,就可以在类内部调用notify

一种notify的私有(private)方法。 (一种,我们知道,我们不能)

这里有一些代码,必须注意synchronized中的OtherThread,这是我想要阻止的:

public class MainThread {

public static void main (String[] args) throws InterruptedException{
Thread.currentThread().setName("Main Thread");
X x = new X();
x.start();

OtherThread y = new OtherThread(x);
y.start();


synchronized (x){
System.out.println(Thread.currentThread().getName()+" Waiting");
x.wait();
}
System.out.println(Thread.currentThread().getName()+": Now I'm running");

}

}

class X extends Thread{


public void run(){
// setting thread name
Thread.currentThread().setName("X");


try {
Thread.sleep(1000*5); // 5 seconds here
} catch (InterruptedException e) {
e.printStackTrace();
}

synchronized (this){
this.notify();// I want only notify/notifyAll inside X to be possible
System.out.println("Notified from "+Thread.currentThread().getName()+" Thread");
}

}
}

class OtherThread extends Thread{
Thread t;

public OtherThread(Thread x){ // pass the X thread to this thread
this.t = x;
}

public void run(){
// setting thread name
Thread.currentThread().setName("OtherThread");

try {
Thread.sleep(1000*1); // 1 second here
} catch (InterruptedException e) {
e.printStackTrace();
}
synchronized (t){
t.notify(); // prevent this. To can't call notify from outside class X.
System.out.println("Notified from "+Thread.currentThread().getName()+" Thread");
}
}

}

最佳答案

嗯,答案是你不能。我的意思是,您根本无法更改 notify/wait 可见性(它们对所有对象都设置为公共(public))

但是,我认为可见性并不是适合您的工具。您正在使用 X 的实例作为您正在等待/通知的监视器。问题是,由于其他未指定的原因,您也将该 X 线程共享给其他线程。因此每个人都可以潜在地调用 wait/notify。

我的建议是使用另一个对象作为监视器(而不是 X 的实例)并仅在需要与其交互的对象之间共享该对象。像这样的东西:

public class MainThread {

public static void main (String[] args) throws InterruptedException{
Thread.currentThread().setName("Main Thread");
Object monitor = new Object();

X x = new X(monitor);
x.start();

OtherThread y = new OtherThread(x);
y.start();


synchronized (monitor){
System.out.println(Thread.currentThread().getName()+" Waiting");
monitor.wait();
}
System.out.println(Thread.currentThread().getName()+": Now I'm running");

}

}

class X extends Thread{

private Object monitor;

public X(Object monitor) {
this.monitor = monitor;
}

public void run(){
// setting thread name
Thread.currentThread().setName("X");


try {
Thread.sleep(1000*5); // 5 seconds here
} catch (InterruptedException e) {
e.printStackTrace();
}

synchronized (this.monitor){
this.monitor.notify();// I want only notify/notifyAll inside X to be possible
System.out.println("Notified from "+Thread.currentThread().getName()+" Thread");
}

}
}

class OtherThread extends Thread{
Thread t;

public OtherThread(Thread x){ // pass the X thread to this thread
this.t = x;
}

public void run(){
// setting thread name
Thread.currentThread().setName("OtherThread");

try {
Thread.sleep(1000*1); // 1 second here
} catch (InterruptedException e) {
e.printStackTrace();
}
synchronized (t){
t.notify(); // this will work, but it wont do anything.
System.out.println("Notified from "+Thread.currentThread().getName()+" Thread");
}
}

}

此外,只有一个优点,我建议您查看更高级的方法来同步它。您可以创建一个 Semaphore (或 CountDownLatch),而不是仅仅共享一个对象来使用它的监视器,它更强大,语义更清晰(这就是我喜欢的)他们)。

**** 编辑 ****

另外,还有一个小建议。 Thread.currentThread().setName("X") 实际上可以通过 this.setName("X") 进行更改,因为您的对象是线程并且知道自己(但你不能在主线程上这样做)。不过,我建议完全删除它,因为 Thread 类公开了一个构造函数,允许您预先设置该名称,因此您可以:

class X extends Thread {

public X() {
super("X")
}

public void run(){
try {
...
}
}

class OtherThread extends Thread{
Thread t;

public OtherThread(Thread x){ // pass the X thread to this thread
super("OtherThread");
this.t = x;
}

public void run(){
try {
...
}

}

关于java - 如何使线程 - notify()/notifyAll() 私有(private),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/29654549/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com