Два потока, выполняющие синхронизированный блок одновременно - PullRequest
0 голосов
/ 24 сентября 2018

Ниже приведен код, в котором Thread входит в синхронизированный блок, ждет в течение 5 секунд и затем выходит.Я запустил два экземпляра Thread одновременно.

Ожидалось, что один из потоков будет владеть блокировкой синхронизируемого объекта, а другой будет ждать.Через 5 секунд, когда владелец блокировки выйдет, будет запущен ожидающий поток.

Но на самом деле оба потока одновременно выполняют синхронизированный блок и одновременно выходят из него.

Ожидаемый результат:

Thread-X <timeX> received the lock.
Thread-X <timeX+5s> exiting...
Thread-Y <timeY> received the lock.
Thread-Y <timeY+5s> exiting...

Фактический результат:

Thread-X <time> received the lock.
Thread-Y <time> received the lock.
Thread-X <time+5s> exiting...
Thread-Y <time+5s> exiting...

Я что-то здесь упустил?

import java.text.SimpleDateFormat;
import java.util.Date;

public class Test2 {
public static void main(String[] args) {
    MyRunnable m = new MyRunnable();
    Thread t = new Thread(m);
    Thread t1 = new Thread(m);
    t.start();
    t1.start();
    }
}

class MyRunnable implements Runnable {
    @Override
    public void run() {
        synchronized (this) {
            try {
                SimpleDateFormat formatter = new SimpleDateFormat("dd/MM/yyyy HH:mm:ss");
                Date date = new Date(System.currentTimeMillis());
                System.out.println(Thread.currentThread().getName() + " " + formatter.format(date) + " received the lock.");
                wait(5000);
                date = new Date(System.currentTimeMillis());
                System.out.println(Thread.currentThread().getName() + " " + formatter.format(date) + " exiting...");
            } catch(InterruptedException ie) {}
        }
    }
}

Ответы [ 3 ]

0 голосов
/ 24 сентября 2018

Использовать

Thread.sleep(5000);

JavaDocs для Thread.sleep:

Заставляет текущий выполняющийся поток спать (временно прекращать выполнение) для указанного числамиллисекунд, в зависимости от точности и точности системных таймеров и планировщиков.Поток не теряет право собственности ни на какие мониторы.

0 голосов
/ 24 сентября 2018

Следующая цитата из Oracle Tutorials объясняет ситуацию:

Когда вызывается wait, поток снимает блокировку и приостанавливает выполнение.

Кроме того, только один поток может выполнить блок synchronized, защищенный тем же объектом!Вызов wait в вашем примере снимает блокировку, позволяя другому потоку получить блокировку.

0 голосов
/ 24 сентября 2018

Ответ лежит в java.lang.Object.wait (long) , документация которого гласит:

[...] Этот метод вызывает текущий поток (вызовите егоT) поместить себя в набор ожидания для этого объекта, а затем отказаться от любых заявлений на синхронизацию для этого объекта .[...]

...