Как проверить состояние метода в Java? - PullRequest
2 голосов
/ 10 августа 2010

Допустим, у меня есть экземпляр метода с именем myMethod (). Мне нужно проверить, если какой-либо поток выполняет метод. Есть ли способ проверить это с помощью рефлексии или другого API?

Я хочу выполнить некоторую логику очистки, когда метод НЕ выполняется. Следовательно, необходимо проверить, работает метод или нет.

Ответы [ 2 ]

6 голосов
/ 10 августа 2010

Невозможно сделать точно то, что вы сказали (проверьте, находятся ли другие потоки внутри метода напрямую).

Однако это звучит как классический случай для синхронизация .Сделайте синхронизацию вызова метода на мониторе какого-либо объекта;Сделайте ваш код очистки синхронизировать на том же мониторе, и вуаля!Теперь, если любой поток выполняет методы, которые вы синхронизировали, ваш код очистки не может быть запущен, но будет ждать, пока все потоки не выйдут из методов, а затем продолжат работу.

Вот пример:

public class Foo
{
    private final Object LOCK = new Object();

    public void importantMethodOne()
    {
        synchronized(LOCK)
        {
            // Method body here
        }
    }

    public void importantMethodTwo()
    {
        synchronized(LOCK)
        {
            // Method body here
        }
    }

    public void otherMethod()
    {
        // Method body here
    }

    public void cleanupMethod()
    {
        synchronized(LOCK)
        {
            // Method body here
        }
    }
}

Монитор LOCK является мьютексом - только один поток может удерживать его одновременно, поэтому только один поток может вызывать любой из важныйMethodOne, ImportantMethodTwo или cleanupMethod одновременно,Любые потоки, которые пытаются вызвать любой из этих методов, пока другой находится в области действия (и, следовательно, имеет блокировку), будут ожидать.В этом примере otherMethod может быть вызван в любое время, не прерывая что-либо еще, потому что он не получает блокировку.

Обратите внимание, что в этом случае два потока не могут выполнить myMethod () одновременно, потому что они будутблоки друг друга .Если это проблема, вы можете обойти это с помощью ReadWriteLock (который позволяет многим «читателям» удерживать ее одновременно, кроме одного «писателя»).Если вы получите блокировку чтения для ваших «обычных» методов и блокировку записи для ваших «очистительных» методов, это будет иметь желаемую семантику.

0 голосов
/ 10 августа 2010

Полагаю, у вас может быть что-то вроде этого: (Используйте отступы, не хочется иметь дело с фигурными скобками сегодня)

int busy;

public boolean is Running()
    synchronized(lock1)
        return busy != 0;

public void run()
    try {
        synchronized(lock1)
            busy++

        do lots of stuff here
    } finally {
        synchronized(lock1)
            busy--
    }

Рано, но мой усталый мозг не может найти проблемы с этим - я перечитал бы это позже и посмотрю, имеет ли это смысл.

Но вам понадобится больше логики синхронизации, чтобы гарантировать, что ничего не входит в нее, пока вы чистите - я не кодировал это, так как сегодня отвечаю на вопрос, который вы задали, а не на тот, который вы хотели задать (другие уже сделал это)

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...