而Loop变量赋值给Runnable
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了而Loop变量赋值给Runnable相关的知识,希望对你有一定的参考价值。
为什么每个Runnable应该为每个设备分配不同的设备时打印相同的设备?
似乎每个Runnable都使用从while循环分配的最后一个设备。如何确保从循环中为每个Runnable分配一个设备?
Iterator<TaskCard> i = taskManager.getTaskCards().iterator();
while (i.hasNext()) {
TaskCard taskCard = i.next();
taskCard.updateTask();
ReturnInterface<String> returnInterface = new TaskReturnIterface(taskManager, taskCard);
Task task = taskCard.getTask();
ProtocolInterface selectedProtocol = task.getDevice().getSelectedProtocol();
selectedProtocol.setTask(task);
selectedProtocol.setReturnInterface(returnInterface);
SwingUtilities.invokeLater(new Runnable() {
final ProtocolInterface mySelectedProtocol=selectedProtocol;
@Override
public void run() {
System.out.println("[Taskmanager.TaskReturnInterface.actionPerformed.RUN()]selectedProtocol device= " + mySelectedProtocol.getDevice());
}
});
}
下面是请求的协议接口代码。
public abstract class ProtocolInterface<N> implements Callable<ReturnInterface<N>>, Serializable{
protected DefaultDevice device;
protected String name = "";
protected Task task;
protected Date scheduledDate;
protected ReturnInterface<N> returnInterface;
final private CredentialInterface credential = new CredentialInterface() {
private String user = "";
private String password = "";
private int port = 22;
@Override
public String getUser() {
return user;
}
@Override
public String getPassword() {
return password;
}
@Override
public int getPort() {
return port;
}
@Override
public void setUser(String s) {
user = s;
}
@Override
public void setPassword(String s) {
password = s;
}
@Override
public void setPort(int p) {
port = p;
}
@Override
public DefaultDevice getHost() {
return device;
}
@Override
public void setHost(DefaultDevice host) {
System.out.println("[ProtocolInterface].CredentialInterface.setHost() host= "+host);
device = host;
}
};
boolean useIP = true;
public ProtocolInterface() {
}
public CredentialInterface getCredential() {
return credential;
}
public ProtocolInterface(String name, DefaultDevice device) {
this.name = name;
this.device = device;
}
public DefaultDevice getDevice() {
return device;
}
public ReturnInterface<N> getReturnInterface() {
return returnInterface;
}
public void setReturnInterface(ReturnInterface<N> returnInterface) {
this.returnInterface = returnInterface;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Task getTask() {
return task;
}
public void setTask(Task task) {
this.task = task;
}
public Date getScheduledDate() {
return scheduledDate;
}
public void setScheduledDate(Date scheduledDate) {
this.scheduledDate = scheduledDate;
}
public abstract Icon getIcon();
public abstract CredentialForm_Interface getCredentialForm();
@Override
public int hashCode() {
int hash = 7;
hash = 47 * hash + Objects.hashCode(this.device);
hash = 47 * hash + Objects.hashCode(this.name);
return hash;
}
@Override
public boolean equals(Object obj) {
if (this == obj) {
return true;
}
if (obj == null) {
return false;
}
if (getClass() != obj.getClass()) {
return false;
}
final ProtocolInterface<?> other = (ProtocolInterface<?>) obj;
if (this.useIP != other.useIP) {
return false;
}
if (!Objects.equals(this.name, other.name)) {
return false;
}
if (!Objects.equals(this.device, other.device)) {
return false;
}
if (!Objects.equals(this.credential, other.credential)) {
return false;
}
return true;
}
@Override
public String toString() {
return name;
}
}
答案
你是对的!您可以参考协议对象创建Runnable
instance。可以更改此引用,直到invokeLater
完成此任务。因此,您必须复制所需的数据而不是保存引用。
SwingUtilities.invokeLater(new Runnable() {
final Device device = selectedProtocol.getDevice();
@Override
public void run() {
System.out.println("[Taskmanager.TaskReturnInterface.actionPerformed.RUN()]selectedProtocol device= " + device);
}
});
另一答案
试试这个:
Iterator<TaskCard> i = taskManager.getTaskCards().iterator();
while (i.hasNext()) {
TaskCard taskCard = i.next();
taskCard.updateTask();
ReturnInterface<String> returnInterface = new TaskReturnIterface(taskManager, taskCard);
Task task = taskCard.getTask();
final ProtocolInterface selectedProtocol = task.getDevice().getSelectedProtocol();
selectedProtocol.setTask(task);
selectedProtocol.setReturnInterface(returnInterface);
SwingUtilities.invokeLater(new Runnable() {
@Override
public void run() {
System.out.println("[Taskmanager.TaskReturnInterface.actionPerformed.RUN()]selectedProtocol device= " + selectedProtocol.getDevice());
}
});
}
另一答案
如果没有关于TaskCard
和其他对象的更多信息,很难说,但你应该尝试声明一些变量final
并尝试打印对象的哈希码,以检查它是否真的是同一个实例或者语义相同的不同实例:
for (Iterator<TaskCard> i = taskManager.getTaskCards().iterator(); i.hasNext();) {
TaskCard taskCard = i.next();
taskCard.updateTask();
ReturnInterface<String> returnInterface = new TaskReturnIterface(taskManager, taskCard);
Task task = taskCard.getTask();
// Mark this as "final" so you can use it as is in any internal anonymous class:
final ProtocolInterface selectedProtocol = task.getDevice().getSelectedProtocol();
selectedProtocol.setTask(task);
selectedProtocol.setReturnInterface(returnInterface);
System.out.println("[1] selectedProtocol device=" + selectedProtocol.getDevice().hashCode());
SwingUtilities.invokeLater(new Runnable() {
@Override
public void run() {
System.out.println("[2] selectedProtocol device=" + selectedProtocol.getDevice().hashCode());
}
});
}
看起来在对象之间可能存在一些关系,可能会打印相同的输出或在后端使用相同的对象。特别是这部分:
ProtocolInterface selectedProtocol = task.getDevice().getSelectedProtocol();
selectedProtocol.setTask(task);
selectedProtocol.setReturnInterface(returnInterface);
看起来很奇怪,因为selectedProtocol
似乎某种程度上绑定了一个与任务绑定的设备本身,那么你必须再次设置它的任务?
它基本上是做task.getDevice().getSelectedProtocol().setTask(task)
,看起来有一些你应该检查的漏洞...
此外,SwingUtilities.invokeLater()
有点保留用于GUI处理,因此您可能希望删除它(除非它正在执行GUI ...)。
以上是关于而Loop变量赋值给Runnable的主要内容,如果未能解决你的问题,请参考以下文章