防止多个线程同时使用多个方法

时间:2014-05-24 10:49:59

标签: java multithreading thread-safety synchronized

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

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不应该使用任何这些方法。是否足以将同步修饰符放在那里?我知道在使用它时应该小心,因为它会减慢程序,因为线程必须等待,但我的程序足够小,速度并不重要。

3 个答案:

答案 0 :(得分:2)

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

答案 1 :(得分:1)

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

  

当线程A调用广播方法时,线程B不应该使用任何这些方法。是否足以将同步修饰符放在那里?

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

答案 2 :(得分:0)

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

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()