java - 在以下上下文中如何确保线程安全?

标签 java multithreading timer locking reentrantlock

我有一个名为 processOutbox 的方法。我希望它是线程安全的。我不希望另一个线程在一个线程运行时调用此方法。我已经通过以下方式实现了它。我做对了吗?我的实现有没有漏洞?如果有任何问题,请告诉我如何解决它。

this.start();
    outboxLock.lock();
    timer = new Timer();
    try{
    timer.scheduleAtFixedRate(new TimerTask() {
            public void run() {
               processOutbox();
            }
        }, 0, period);
    } finally{
        outboxLock.unlock();
    }

最佳答案

如果你想让你的方法processOutbox,你应该使用关键字synchronized:

public class YourClass{
    public synchronized void processOutbox(){
         //do all you want
    }
}

更多信息请访问:https://docs.oracle.com/javase/tutorial/essential/concurrency/syncmeth.html

如果在您的代码中有一个 YourClass 的实例,例如 myInstance ,所有对 processOutbox() 的调用都将是线程安全的,因为它们将被锁定在实例级别.

例如:

YourClass myInstance = new YourClass();
 Thread thread1 = new Thread(){
    public void run(){
      myInstance.processOutbox();
    }
  }
 Thread thread2 = new Thread(){
    public void run(){
       myInstance.processOutbox();
    }
  }
thread1.start();
thread2.start();

这里 thead2 将等待直到 thread1 完成对“processOutbox”的调用

但是例如:

YourClass myInstance = new YourClass();
YourClass myInstance2= new YourClass();
Thread thread1 = new Thread(){
    @Override
    public void run(){
        myInstance.processOutbox();
    }
};
Thread thread2 = new Thread(){
    @Override
    public void run(){
        myInstance2.processOutbox();
    }
}
thread1.start();
thread2.start();

thead2 将等待,因为他们在不同的实例上调用该方法。

有人特别询问有关使用 ReentrantLock 的问题——因此我将此回复添加到此回复中,因为此回复是正确的。

public class YourClass {
    private Lock outboxLock = new ReentrantLock();
    public void processOutbox() {
        outboxLock.lock()
        try {
            // do stuff
        } finally {
            outboxLock.unlock()
        }
    }
}

我特别提到这一点是因为您还可以做一些事情,在这种情况下,您可以通过使用 tryLock 来避免其他线程被锁定而不会导致它们阻塞。

public class YourClass {
    private Lock outboxLock = new ReentrantLock();
    public void processOutbox() {
        if( outboxLock.tryLock() ) {  
            try {
                // do stuff
            } finally {
                outboxLock.unlock()
            }
        }
    }
}

关于java - 在以下上下文中如何确保线程安全?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/32710303/

相关文章:

java - JUnit for future.get() 异常场景

java - Wicket 应用程序、序列化和 Java 计时器

c# - 可以将异步事件处理程序附加到 System.Timers.Timer 吗?

java - 如何修复NullPointerException,jsoup元素

java - 无法在 [java] 中执行计时器

java - 如何在 Eclipse 中获取方法的 VM 方法签名?

Java Spring,等待 AsyncHandlers

c++ - 如何创建一个线程传递指定对象的成员函数?

c# - 使用信号量调用 WaitOne 是否会释放调用线程以执行其他工作?

java - CardBuilder Layout.AUTHOR 切换元素顺序