Пропуск метода, когда он уже выполнен другим потоком - PullRequest
0 голосов
/ 30 апреля 2020

Мой вопрос связан с этим: Выйдите из метода, если его выполняет другой поток

Есть метод, который выполняется несколькими потоками. Если один поток выполняет метод, любой другой поток должен просто выйти. Мое решение таково:

public class ReentrantLockTest implements Runnable {

    private static final ReentrantLock LOCK = new ReentrantLock();

    @Override
    public void run() {
        if (LOCK.tryLock()) {
            System.out.println("Aquired. Thread "  + Thread.currentThread().getId());
            try {
                // do stuff here

            } catch (Exception e) {
                // handle errors
            } finally {
                // release the lock
                LOCK.unlock();
            }
        }
    }

Мне кажется, что это нормально, но на производстве иногда случается, что блокировка остается невыпущенной, поэтому метод вообще не выполняется, пока я не перезапущу систему.

Итак, у меня два вопроса: 1. Как это возможно, что блокировка не снимается? 2. Что такое хороший способ тестирования такого кода? Просто запустите это в al oop и надеемся, что в какой-то момент он сломается sh, если есть ошибка, которая не кажется хорошим решением.

Ответы [ 2 ]

0 голосов
/ 30 апреля 2020
package thread;
import java.util.concurrent.locks.ReentrantLock;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

public class ReentrantLockTest implements Runnable 
{
    private static final ReentrantLock LOCK = new ReentrantLock();
    @Override
    public void run() 
    {
        boolean done = false; 
        while (!done) 
        {
            boolean ans=LOCK.tryLock();
        if(ans) 
            {
            System.out.println("Aquired. Thread "  + Thread.currentThread().getId());
            try {
                // do stuff here
                System.out.println(Thread.currentThread().getName()+ " in try block");
                done = true;    
            }catch (Exception e) {
                // handle errors
            } finally {
                // release the lock
                LOCK.unlock();
                System.out.println(Thread.currentThread().getName()+" unlock");
                }
            }
        else
            { 
            System.out.println(Thread.currentThread().getName()  + " waiting for lock"); 
            try
            {Thread.sleep(1000);} 
            catch(InterruptedException e) 
                {e.printStackTrace();} 
            }
      }
   }
}


public class ReentrantLockDemo2 
{
    public static void main(String[] args) 
    {
        ExecutorService pool=Executors.newFixedThreadPool(5);
        Runnable t1=new ReentrantLockTest();
        Runnable t2=new ReentrantLockTest();
        Runnable t3=new ReentrantLockTest();
        Runnable t4=new ReentrantLockTest();

        pool.execute(t1);
        pool.execute(t2);
        pool.execute(t3);
        pool.execute(t4);

        pool.shutdown();
        System.out.println("Main Close");
    }
}
0 голосов
/ 30 апреля 2020

Вы должны использовать ключевое слово synchronized . Это гарантирует, что только один поток выполняет блок кода одновременно.

Измените ваш метод на:

public synchronised void run() {
   //your code
}
...