我有一个单例类,可以在链接列表中添加和删除客户端(applet),如下所示:
public class ClientManager {
//Collections.unmodifiableList
private static ClientManager instance = new ClientManager();
private static LinkedList<Bot> Clients = new LinkedList<>();
//private constructor here..
public static Bot add(final Bot bot) {
Clients.add(bot);
new Thread(new Runnable() {
@Override
public void run() {
while (bot.getApplet() == null) {
Utilities.sleep(10);
}
}
}).start();
return bot;
}
public static Bot remove(int hashCode) {
for (Iterator<Bot> it = Clients.iterator(); it.hasNext();) {
Bot bot = it.next();
if (bot.getCanvas().getClass().getClassLoader().hashCode() == hashCode) {
it.remove();
return bot;
}
}
return null;
}
public static Bot getBot(int hashCode) {
for (Bot bot : Clients) {
if (bot.getCanvas() != null && (bot.getCanvas().getClass().getClassLoader().hashCode() == hashCode)) {
return bot;
}
}
return null;
}
}
然后我有一个带有JTabbedPane的JFrame,每个Tab上都有一个带有actionListener的退出按钮:
CloseButton.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
Frame.this.removeBot((Loader) component);
}
});
//Need to synchronize this function some how so that when I run it in a new Thread, they don't all access the LinkedList at the same time..
private void removeBot(final Loader loader) {
Frame.this.TabPanel.remove(loader); //Need to synchronize this or tabbedpane throws.. This call removes a tab..
List<Bot> Clients = ClientManager.getBots();
for (Iterator<Bot> it = Clients.iterator(); it.hasNext();) {
Bot bot = it.next();
if (bot != null && bot.getLoader() != null && bot.getLoader() == loader) {
it.remove();
loader.destruct(); //Destroy my applet. Calls applet.stop() and then applet.destroy()
}
}
System.gc();
}
问题:
如何同步删除Tabs,以便TabbedPane在多个线程尝试删除选项卡时不会抛出,以及如何同步我的删除功能,以便多个线程不会同时从LinkedList中删除如果我在一个新线程中运行上述任何一个,它会抛出错误..
我尝试查看教程,然后在我的函数之前放置了synchronized,但这没有帮助。
答案 0 :(得分:1)
添加2个锁:
A)
synchronized( Frame.this.TabPanel ) {
... remove etc until the end of the method
}
将此添加到您向TabPanel添加内容的代码中:
synchronized( Frame.this.TabPanel ) {
...add the loader here...
}
b)中
机器人列表相同:
synchronized( Clients ) {
Clients.add(bot);
new Thread(new Runnable() {
@Override
i.e. the contents of the add method
}
删除方法开头的相同内容
public static Bot remove(int hashCode) {
synchronized( Clients ) {
for (Iterator<Bot> it = Clients.iterator(); it.hasNext();) {
Bot bot = it.next();
if (bot.getCanvas().getClass().getClassLoader().hashCode() == hashCode) {
it.remove();
return bot;
}
}
return null;
}// synchronized
}
然后在removeBot!
synchronized( Clients ) {
for (Iterator<Bot> it = Clients.iterator(); it.hasNext();) {
Bot bot = it.next();
if (bot != null && bot.getLoader() != null && bot.getLoader() == loader) {
it.remove();
loader.destruct(); //Destroy my applet. Calls applet.stop() and then applet.destroy()
}
}
}