【问题标题】:Preventing usage of multiple methods by several threads simultaneously防止多个线程同时使用多个方法
【发布时间】:2014-05-24 10:49:59
【问题描述】:

我正在为聊天室编写服务器并遇到以下问题。 我有添加、删除和操作用户的方法。简化后看起来像这样:

User[] users = new User[8];

public synchronized void addUser(User u) {
    for (int i = 0; i < 8; i++)
        if (users[i] == null)
            users[i] = u;
}

public synchronized void broadcast(String s) {
    for (User u: users)
        u.sendMessage(s);
}

public synchronized void removeUser(User s) {
    for (int i = 0; i < 8; i++)
        if (users[i] == s)
            users[i] = null;
}

我不确定这是否足够。我想让这个线程安全。一个例子: 我有线程 A 和 B,都可以访问这些方法。当线程 A 调用广播方法时,线程 B 应该不能使用这些方法中的任何一个。将同步修饰符放在那里就足够了吗?我知道使用它时应该小心,因为它会减慢程序的速度,因为线程必须等待,但我的程序足够小,速度并不重要。

【问题讨论】:

    标签: java multithreading thread-safety synchronized


    【解决方案1】:

    假设所有三个方法都属于同一个类,并且所有线程都具有该类的相同instancesynchronized 足以确保这三个方法中只有一个可以执行在任何时候。如果另一个线程在线程执行时尝试运行这三种方法之一,则第二个线程将自动等待该方法完成。

    【讨论】:

    • 是的,它们都是同一类的一部分,我只制作了一个对象。所以他们是安全的?
    • Octopus 说这只适用于一个函数(A 调用广播(),但 B 可以调用 addUser())。我希望当 A 调用广播()时 B 不能执行任何这些函数。谁是对的?
    • @Genuigr synchronized 是每个实例,而不是每个实例+方法。请参阅this tutorial from Oracle,阅读“使这些方法同步有两个效果:”部分的第一个要点。
    【解决方案2】:

    代码仅在特定实例上同步。这将只允许单个线程在特定时间调用其实例上的方法。即在任何时间点每个实例每个方法每个线程。要回答您的问题,

    当线程 A 调用广播方法时,线程 B 应该不能使用这些方法中的任何一个。将同步修饰符放在那里就足够了吗?

    是的,代码足够安全,在线程A释放锁之前,它不会允许线程B同时调用实例上的任何方法 em>

    【讨论】:

    • 我觉得第二段不正确,你可以考虑修改一下
    • @Marco13 我修改了它。我想我现在说得对了。
    【解决方案3】:

    除了前面的答案,对于线程不安全的操作,您可以使用锁。这是一个简单的例子:

    import threading
    
    theLock = threading.Lock()
    
    def foo():
        global theLock
    
        #acquire the lock, thread will wait until no other thread has the lock
        theLock.acquire()
    
        #do something
        bar()   
    
        #release lock so that other threads may acquire it, if other thread is waiting for lock it may be launched immediately
        theLock.release()
    

    【讨论】:

      猜你喜欢
      • 2012-01-25
      • 2014-01-15
      • 1970-01-01
      • 1970-01-01
      • 2019-08-13
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多