繁体   English   中英

JAVA 同步块在多线程环境中不起作用

[英]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();

现在对于t1t2 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

租用锁: https://javarevisited.blogspot.com/2013/03/reentrantlock-example-in-java-synchronized-difference-vs-lock.html

正如评论中所述,您正在对不同的对象进行同步,因此线程之间没有协调。

相反,您需要让线程共享它们同步的 object。 您可以在MainOpenServerSockets中创建 object,然后将其传递给ClientResponder的构造函数,然后ClientResponder可以在该 object 上进行同步。

但还有其他可能的问题:

  1. 不清楚为什么OpenServerSockets应该是一个Thread
  2. OpenServerSockets在一个紧密的循环中不断产生新线程似乎很奇怪
  3. 您将整个ClientResponder run方法包装在一个synchronized块中。 这意味着在线程的整个使用寿命期间,它都持有锁。 这似乎不太可能是您所需要的。
  4. 通常,最佳实践是实现Runnable而不是扩展Thread ,然后将实现Runnable的 class 的实例传递给new Thread

Re #2: ClientResponderrun应该看起来像这样:

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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM