在另一个 Runnable 实现类中传递 Runnable 实例,其中前者的 run() 方法需要稍后的引用



我有一个类'ResourceConsumerThread',它扩展了Thread并定义了一些行为。此类的多个实例(即多个线程(将具有不同的行为。我正在尝试通过函数接口(Runnable(传递这些行为,同时创建ResourceConsumerThread类的实例。ResourceConsumerThread 的 run(( 方法只需调用 lambda 的方法 - run((。但是,我的要求是我传递的lambda需要引用它被传递到的ResourceConsumerThread对象。

public class ResourceConsumingThread extends Thread {
//threads which have acquired resources that this thread is asking for.
private List<ResourceConsumingThread> dependencyList;
private List<Resource> acquiredResources;
private List<Resource> requestedResources;
private volatile boolean isDeadlockDetected;
private final String id;
private static int threadIdGenerator;
private final Runnable runnableBody;
private ResourceConsumingThread( Runnable runnableBody) {
this.dependencyList = new ArrayList<>();
this.acquiredResources = new ArrayList<>();
this.requestedResources = new ArrayList<>();
this.id = "T" + threadIdGenerator++;
this.runnableBody = runnableBody;
}
@Override
public void run() {
System.out.println("Running body for thread : " + id);
if(runnableBody != null){
runnableBody.run();
}else{
System.out.println("ERROR...threadBody can't be null.");
}
}
}

此类的用户将像下面这样使用它:

public void callerMethod(){
ResourceConsumingThread t1 = lockManager.createNewThread(new Runnable() {
@Override
public void run() {
lockManager.acquireLockOnResourceForThread(new Resource(), t1);
}
});
}

但是,由于 t1 尚未构建,因此我无法在 run(( 方法中使用它 - 我收到编译器错误。

知道我如何实现这一点,即使它涉及一些设计返工?主要要求是:

  1. LockManager.acquireLockOnResourceForThread(( 需要知道哪个 ResourceConsumingThread 实例正在请求哪个资源。
  2. ResourceConsumingThread 的 run(( 方法应该能够在单独的线程中执行不同的逻辑。

更新了我正在尝试的答案(不确定它是否正确(。仍在等待通过社区解决潜在解决方案的其他天使。

final Map<String, Resource> resourceMap = new HashMap<>();
resourceMap.put("R1", new Resource());
final ResourceConsumingThread t1 = new ResourceConsumingThread();
Runnable t1Runnable = new Runnable() {
@Override
public void run() {
lockManager.acquireLockOnResourceForThread(resourceMap.get("R1"), t1);
}
};
t1.setRunnableBody(t1Runnable);
t1.start();
t1.join();

更新(在@Cliff的评论之后(:

ResourceConsumingThread t = lockManager.createNewThread(() -> {
lockManager.acquireLockOnResourceForThread(new Resource(), (ResourceConsumingThread) Thread.currentThread());
});

您可以简单地在匿名内部类中使用this

public void callerMethod(){
ResourceConsumingThread t1 = lockManager.createNewThread(new Runnable() {
@Override
public void run() {
lockManager.acquireLockOnResourceForThread(new Resource(), this);
}
});
}

这将传递对callerMethod中称为t1Runnable的引用。

我建议创建一个函数接口,在其运行方法中接受ResourceConsumingThread。

interface ResourceRunnable {
void run(ResourceConsumingThread resourceThread);
}

这意味着更改 ResourceConsumingThread 的构造函数以接受 ResourceRunnable。然后你可以做:

public void callerMethod(){
ResourceConsumingThread t1 = lockManager.createNewThread(new Runnable() {
@Override
public void run(ResourceConsumingThread resourceThread) {
lockManager.acquireLockOnResourceForThread(new Resource(), resourceThread);
}
});
}

其中 ResourceConsumingThread 会在内部调用 ResourceRunnable.run(this(。

更新:正如我通过评论建议的那样,另一种方法是:

ResourceConsumingThread t = lockManager.createNewThread(() -> {
lockManager.acquireLockOnResourceForThread(new Resource(), (ResourceConsumingThread) Thread.currentThread());
});

最新更新