Монитор (семафор) в Java - PullRequest
       11

Монитор (семафор) в Java

0 голосов
/ 02 декабря 2018

Я читал и выполнял практические занятия на языке java из книги Герберта Шильдта «Полный справочник».
В этой книге в главе «Тема» есть раздел «Общение между нитями».
В одной из боковых книг сказано «нет».другой синхронизированный метод экземпляра выполняется любым потоком, пока текущий поток не завершится, но посмотрите на программу ниже.
В выводе он выполняет оба синхронизированных метода, как кто-то может объяснить, что происходит?

вывод:

положить: 0
положить: 1
положить: 2
положить: 3
положить: 4
получить: 4
получить: 4
получить: 4
получить: 4
получить: 4
получить: 4
получить: 4
получить: 4
получить: 4
получить: 4
получить: 4
получить: 4
получить: 4
получить: 4
получить: 4
получить: 4
получить: 4
получить: 4
получить:4
получить: 4
получить: 4
получить: 4
получить: 4

class Main{
    public static void main(String args[]){
        Q q=new Q();

        Producer p=new Producer(q);
        Consumer c=new Consumer(q); 
    }
}

class Q {
    int n;

    synchronized int get(){
        System.out.println("get :"+n);
        return n;
    }
    synchronized void put(int n){
        this.n=n;
        System.out.println("put :"+n);
    }
}



class Producer implements Runnable{
    Q q;
    Producer(Q q){
        this.q=q;
        new Thread(this,"Producer").start();

    }
    public void run(){
        int i=0;
        while(true){
            q.put(i++);
        }
    }
}

class Consumer implements Runnable{
    Q q;
    Consumer(Q q){
        this.q=q;
        new Thread(this,"Consumer").start();
    }

    public void run(){
        while(true){
            q.get();
        }
    }
}

1 Ответ

0 голосов
/ 02 декабря 2018

Извлечение из Java-документов ,

невозможно выполнить два вызова синхронизированных методов одного и того же объекта для чередования.Когда один поток выполняет синхронизированный метод для объекта, все остальные потоки, которые вызывают синхронизированные методы для того же блока объекта (приостанавливают выполнение), пока первый поток не завершится с объектом

Итак, завершениеозначает не сам поток ( например: Consumer не ожидает, пока Producer не умрет или не завершится, и наоборот) , но завершит выполнение любых методов / блоков синхронизации.

Toответьте на ваш вопрос, однако Producer и Consumer оба могут работать с использованием Q, но оба метода get и put никогда не будут выполняться одновременно из-за неявной синхронизации с экземпляром объекта с ключевым словом synchronized,

Только один метод будет выполнен либо Producer, либо Consumer в любой момент времени, то есть, когда get вызывается Consumer, Producer не может вызвать put и наоборот..

...