Почему функция availablePermits () не дает правильного результата в моем коде |Потоки Java |Семафор | - PullRequest
0 голосов
/ 29 января 2019

В моем коде количество доступных разрешений для потоков равно 5, и я использую функцию acqu (int permissions), чтобы уменьшить количество разрешений до 2, но когда я запускаю свой код, первый поток дает мне 3, это имеет смысл, но когда следующий поток выполнилДоступно разрешений 1, поэтому почему это происходит, я не понимаю, пожалуйста, помогите мне, я новичок в Java.

Вот мой код:

import java.util.concurrent.Semaphore;

class HelpMe
{
  private Semaphore sema = new Semaphore(5);

  void question()
  {
    try
    {
      sema.acquire(2);
      System.out.println("Available permits : " + sema.availablePermits());
      Thread.sleep(3000);
      sema.release(2);
    }
    catch (InterruptedException e)
    {
      e.getMessage();
    }
  }
}

class JavaExperts implements Runnable
{
  private HelpMe help_me;

  JavaExperts(HelpMe help_me)
  {
    this.help_me = help_me;
  }

  @Override public void run()
  {
    help_me.question();
  }
}

public class Main
{
  public static void main(String[] args)
  {
    HelpMe help_me = new HelpMe();
    Thread one = new Thread(new JavaExperts(help_me));
    Thread two = new Thread(new JavaExperts(help_me));
    Thread three = new Thread(new JavaExperts(help_me));
    Thread four = new Thread(new JavaExperts(help_me));
    one.start();
    two.start();
    three.start();
    four.start();
  }
}

Вывод:

Доступные разрешения: 1

Доступные разрешения: 3

Доступные разрешения: 3

Доступные разрешения: 1

Кодовое изображение: код и вывод

Ответы [ 2 ]

0 голосов
/ 29 января 2019

Этот семафор private Semaphore sema=new Semaphore(5); допускает 5 «единиц», когда поток пытается достичь значения try{ sema.acquire(2);, доступные «единицы» будут 5 - 2.Затем другой поток попытается достичь значения try{ sema.acquire(2);, и доступные «единицы» будут 5 - 2 - 2.На данный момент доступные «единицы» равны 1, а другие потоки пытаются получить 2, поэтому нет доступных «единиц», и эти другие потоки будут заблокированы, пока не будет доступно по меньшей мере 2 единицы наtry{ sema.acquire(2);.Когда один из этих потоков выпускает 2 «единицы» в sema.release(2);, доступные «единицы» будут 5 - 2 -2 + 2, а другой поток может получить «2 единицы» в try{ sema.acquire(2);.

В то же время,в этих строках могут находиться два потока:

  System.out.println("Available permits : " + sema.availablePermits());
  Thread.sleep(3000);

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

0 голосов
/ 29 января 2019

Проблема в том, что эти две строки:

sema.acquire(2);
System.out.println("Available permits : " + sema.availablePermits());

могут выполняться разными потоками.Я имею в виду, что Thread1 может вызывать sema.acquire(2) и до того, как достигнет System.out.println, Thread2 может вызвать, что ema.acquire(2) снова , только после этого System.out.println из Thread1 будет выполнено.

У вас есть один экземпляр HelpMe, который совместно используется всеми этими потоками, и поскольку доступно 5 разрешений, и вы получаете только два (осталось 3 знака),любой последующий поток может получить еще два;таким образом, два потока могут свободно выполнять этот код.

...