[英]JAVA synchronized block not working in a multithreaded environment
我有下面的代码并试图理解为什么这里没有实现同步:
class Main {
Thread t1 = new OpenServerSockets();
t1.start();
}
public class OpenServerSockets extends Thread {
@Override
public void run() {
while(true){
Thread t = new ClientResponder(clientSocket, dis, dos);
t.start();
}
}
public class ClientResponder extends Thread {
@Override
public void run(){
synchronized(this) {
// some other static method call in another class.
}
}
}
同步块被多个线程同时调用。 为什么会这样? 不应该以这种方式使用同步块来确保代码的互斥执行吗?
我可以看到锁在this
上面。
Thread t1 = new ClientResponder();
Thread t2 = new ClientResponder();
现在对于t1
和t2
this
指的是不同的对象。 您需要一个 class 级别锁。
public class ClientResponder extends Thread {
@Override
public void run(){
synchronized(ClientResponder.class) {
// some other static method call in another class.
}
}
}
更好的方法是使用ReentrantLock
。 它提供了syncronized
不提供的高级功能
class ClientResponder extends Thread {
public static final ReentrantLock lock = new ReentrantLock ();
@Override
public void run() {
lock.lock ();
// task.
lock.unlock ();
}
}
快速阅读以供参考: Java 同步块 for.class
正如评论中所述,您正在对不同的对象进行同步,因此线程之间没有协调。
相反,您需要让线程共享它们同步的 object。 您可以在Main
或OpenServerSockets
中创建 object,然后将其传递给ClientResponder
的构造函数,然后ClientResponder
可以在该 object 上进行同步。
但还有其他可能的问题:
OpenServerSockets
应该是一个Thread
OpenServerSockets
在一个紧密的循环中不断产生新线程似乎很奇怪ClientResponder
run
方法包装在一个synchronized
块中。 这意味着在线程的整个使用寿命期间,它都持有锁。 这似乎不太可能是您所需要的。Runnable
而不是扩展Thread
,然后将实现Runnable
的 class 的实例传递给new Thread
。 Re #2: ClientResponder
的run
应该看起来像这样:
public void run(){
while (this.running) {
synchronized (this.objectToSynchronizeOn) {
// Do one unit of work that requires synchronization
}
}
}
这样,每个线程都有机会在其他线程完成的工作之间做一些事情。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.