2013-05-06 73 views
2

我有一个单例类,添加和删除客户端程序(applets)/从一个链表,像这样:如何同步线程

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这对一个退出按钮每个标签具有的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(); 
    } 

问:

如何同步去除标签,使得的TabbedPane当多线程试图删除一个选项卡以及如何同步我的删除功能,以便多个线程不会同时从LinkedList中删除,因为如果我在新的线程中运行上述任何一个时抛出错误,则不会抛出。

我试着看教程,我把我的功能之前同步,但没有帮助。

+1

1为[SSCCE](http://sscce.org) – MarioDS 2013-05-06 18:55:38

+0

[I要给它.. SomethingManager](http://www.codinghorror.com/blog/2006/03/i-应呼叫-IT-somethingmanager.html)。另外,关于你的第一句话“我有一个单身人士”。我不知道你是否阅读了很多关于它们的内容,但是[这里是关于它们的一个很好的讨论](http://stackoverflow.com/questions/137975/what-is-so-bad-about-singletons)。 – Patrick 2013-05-06 19:32:43

+0

我必须使用单例,因为如何让所有类访问单个资源?我希望资源可以被所有的类和方法访问,并且singleton符合这个描述,因为它跟踪了我运行多少个机器人。还好,我将重命名为ClientPool。 – Brandon 2013-05-06 20:07:30

回答

1

添加2把锁:

一)

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 
    } 

在remove方法

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() 
     } 
    } 
    } 
+1

Ohh哇..我添加了两个变量来锁定TabbedPane,因为它不是最终我必须做的:private static final Object TabPaneLock = new Object(); 和synchronized(TabPaneLock);我可以使用对象锁来替换同步的(Frame.this.TabbedPane)吗? – Brandon 2013-05-06 19:17:37

+1

当然,您可以使用sync ...(TabPaneLock)替换sync ...(TabbedPane) - 实际上使用专用的锁定对象会更好。 – xtraclass 2013-05-07 17:35:27