我有一个课程' ResourceConsumerThread'它扩展了Thread并定义了一些行为。此类的多个实例(即多个线程)将具有不同的行为。我正在尝试通过功能接口(Runnable)传递这些行为,同时创建ResourceConsumerThread类的实例。 ResourceConsumerThread的run()方法只需调用lambda的方法 - run()。但是,我的要求是传递的lambda i需要引用它传递给它的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()方法中使用它 - 我收到了编译错误。
任何想法如何实现这一点,即使它涉及一些设计返工?主要要求是:
更新了答案我尝试(不确定它是否正确的做法)。仍然在等待社区潜在解决方案的其他天使。
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&#39;之后):
ResourceConsumingThread t = lockManager.createNewThread(() -> {
lockManager.acquireLockOnResourceForThread(new Resource(), (ResourceConsumingThread) Thread.currentThread());
});
答案 0 :(得分:0)
您可以在匿名内部类中使用this
:
public void callerMethod(){
ResourceConsumingThread t1 = lockManager.createNewThread(new Runnable() {
@Override
public void run() {
lockManager.acquireLockOnResourceForThread(new Resource(), this);
}
});
}
这会将对Runnable
中已知的callerMethod
的引用传递为t1
。
答案 1 :(得分:0)
我建议创建一个在其run方法中接受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());
});