簡體   English   中英

While循環變量分配給Runnable

[英]While Loop variable assignment to 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());
        }
    });

}

以下是wsa請求的協議接口代碼。

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實例。 該引用可以更改,直到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 ...)。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM