我正在为聊天室编写服务器并遇到以下问题。 我有添加,删除和操作用户的方法。简化它看起来像这样:
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不应该使用任何这些方法。是否足以将同步修饰符放在那里?我知道在使用它时应该小心,因为它会减慢程序,因为线程必须等待,但我的程序足够小,速度并不重要。
答案 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()