Синхронизация потоков в Java - PullRequest
0 голосов
/ 07 декабря 2018

Почему мне не удается выполнить синхронизацию в этой части программы:

class P
{

synchronized void pp(String s)
    {
        System.out.println (s);
    }
}

class threadA extends Thread 
{
    P ob;
    String s;
    threadA (P ob, String s)
    {
        this.ob = ob;
        this.s = s;
    }
    public void run ()
    {
        for (int i=1;i<=5;++i)
        {
        ob.pp (s);
        try
        {
            Thread.sleep (1000);
        }
        catch (Exception e) {}
        }
    }
}


class gain 
{
    public static void main(String[] args) {
        P ob = new P ();
        threadA a = new threadA (ob,"Hello User");
        threadA b = new threadA (ob,"Bye User");
        a.start();
        b.start();
    }
}

OP:

Привет, пользователь

Пока, пользователь

Привет, пользователь

Пока, пользователь

Пока, пользователь

...

Я хочу OP в виде:

ПриветПользователь

Привет пользователь

Привет пользователь ..

Пока пользователь

Пока пользователь

Пока пользователь ..

или моя концепция синхронизации неверна?

Ответы [ 4 ]

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

Можете ли вы объяснить мне процесс управления моей программой?

«Привет» запускается и проходит через цикл, пока не достигнет метода synchronized

«Пока» делает то же самое.

«Привет» - этосначала получить блокировку.

«Пока» блокирует ожидание блокировки.

«Hello» выполняет метод и снимает блокировку.

Теперь «пока» можно получитьблокировка и «Hello» сняли его

«Пока» теперь может выполнять метод и снимает блокировку как «Hello».

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

Удерживайте блокировку и не отпускайте ее, если хотите сохранить ее.

public void run() {
    synchronized(ob); { // hold the lock the whole time
        for (int i = 1; i <= 5; ++i) {
            ob.pp (s);
            try { Thread.sleep(1000); } catch (Exception e) {}
        }
    } // releases the lock here.
}
0 голосов
/ 07 декабря 2018

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

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

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

Вы должны попробовать что-то вроде этого

class P
{

void pp(String s)
    {
        System.out.println (s);
    }
}

class threadA extends Thread 
{
    P ob;
    String s;
    threadA (P ob, String s)
    {
        this.ob = ob;
        this.s = s;
    }
    public void run ()
    {
        for (int i=1;i<=5;++i)
        {
            synchronized(ob)
            {
               ob.pp (s);
                try
                {
                    Thread.sleep (10);
                }
                catch (Exception e) {}
            }


        }
    }
}


public class gain 
{
    public static void main(String[] args) {
        P ob = new P ();
        threadA a = new threadA (ob,"Hello User");
        threadA b = new threadA (ob,"Bye User");
        a.start();
        b.start();
    }
}

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

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

Вы не можете выполнить такую ​​синхронизацию из класса P.Теперь происходит то, что любые вызовы pp() блокируются, если другой поток в настоящее время выполняет метод.Пока метод завершается (что быстро, если вы просто собираетесь печатать данные на консоль), следующему потоку будет разрешено ввести метод.

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

Обновление

Вы хотели визуализировать происходящее, поэтому я сделаю это здесь.

  1. Вы создали 2потоки.
  2. Вы запускаете первый поток.
  3. Первый поток начинает работать, в то время как через некоторое время начинает работать и второй поток.
  4. Когда ваш первый поток запускается, это идет к петле for.Затем он вызывает P.pp().
  5. Когда P.pp() вызывается из первого потока, он блокирует объект P.
  6. Поскольку метод очень короткий,он выйдет очень быстро.
  7. Когда метод завершается, он снимает блокировку на P.
  8. Если ваш второй поток достигает блока synchronize до выхода из первого потока,он будет ждать (заблокирован).
  9. Когда выйдет первый поток, второй поток входит, так как первый поток снимает блокировку.
  10. Первый поток возвращается в цикл и пытается вызвать P.pp() снова.
  11. Это будет продолжаться, в зависимости от того, какой поток быстрее, порядок выполнения будет другим.
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...