Обработка нитей сервлетов - PullRequest
0 голосов
/ 10 февраля 2020

Мой сервлет входа в систему получает запрос и после ответа спит 1 минуту.

Моя цель - разрешить доступ двум запросам, и, если приходит третья транзакция, она должна ждать, пока одна из других потоки завершают свою соответствующую задачу.

Мой код проверяет, какие потоки спят, а какие нет. У меня проблема в том, что когда поток просыпается, я хочу иметь возможность назначить ему задачу. Нужно ли опрашивать или есть какой-то способ синхронизации? Как мне подойти к этому?

public class Home extends HttpServlet 
{
    static HttpSession ses;
    static List<Thread> homethread = new ArrayList<Thread>();
    protected void service(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException 
    {
        ses = request.getSession();
        homethread.add(Thread.currentThread());
        for(Thread th : homethread)
        {
            if(th.getState()!=Thread.State.TIMED_WAITING)
            {
                System.out.println("This Thread is Not in Waiting State -> "+th.getName()+"Its State -> "+th.getState());
            }
            else
            {
                System.out.println("A Thread Is In Waiting State -> "+th.getName()+"Its State -> "+th.getState());
            }
            System.out.println("Thread Details->"+th+"Thread State->"+th.getState().TIMED_WAITING);
        }
        response.setContentType("text/html");
        PrintWriter writter = response.getWriter();
        writter.println
        (
                "<!DOCTYPE html>" + 
                "<html>" + 
                "<body>" +  
                "<img src=\"C:\\Users\\surya-pt3101\\Pictures\\Screenshots\\Screenshot (1).png\">"+
                "<h1 style=\"text-align:center;\">Provide Your Choice</h1>"+
                "<form action=\"Upload\" method=\"POST\" enctype=\"multipart/form-data\">" + 
                "<div style=\"text-align:center\">Upload File     :<input type=\"file\" name=\"UploadedFile\" multiple/><input type=\"submit\" value=\"Upload\"><br><br>"+
                "</form>" + 
                "<div style=\"text-align:center\">View Files     :<input type=\"submit\" formaction=\"View\" formmethod=\"post\" value=\"View\"/><br><br>" + 
                "<div style=\"text-align:center\"><input type=\"submit\" formaction=\"LogOut\" formmethod=\"post\" value=\"LogOut\"/>" + 
                        "</body>" + 
                        "</html>"
        );
        response.flushBuffer();
        try 
        {
            Thread.currentThread().sleep(60000);
        } 
        catch (InterruptedException e) 
        {
            e.printStackTrace();
        }
    }
}

1 Ответ

0 голосов
/ 10 февраля 2020

Сервлеты по определению должны быть поточно-ориентированными. Tomcat (или любой другой контейнер сервлета) внутренне содержит пул потоков, которые будут выполнять ваши запросы. Поэтому я не вижу особого смысла в создании собственных потоков (конечно, если мы говорим о не очень сложных вычислениях). Чтобы сделать ваш класс безопасным для потока, есть несколько вариантов: общие методы синхронизации (например, synchronized / wait / notify) или более высокоуровневые структуры (см. Пакет java .util.concurrent). Следует избегать других общих не поточно-ориентированных объектов, таких как ArrayLists. Как я понимаю, вы хотите выполнять не более 2-х потоков одновременно. Вы написали «3-й запрос должен быть обработан в завершенном потоке» - мне кажется, что нецелесообразно, если вы в состоянии выполнить все необходимые вычисления в своих потоках сервлета. Ниже приведен фрагмент, использующий java .util.concurrent.Semaphore - класс, который позволяет обрабатывать только n потоков за один раз, где n - количество разрешений.

public class Home extends HttpServlet {

  private final Semaphore semaphore = new Semaphore(2);

  protected void service(HttpServletRequest request, HttpServletResponse response) {
      try {
          semaphore.acquire();
          // Do what you need
      } catch (InterruptedException e) {
          throw new RuntimeException(e);
      } finally {
          semaphore.release();
      }
  }
}

UPD: пример загрузчика

Представим, что у вас есть форма с полем и кнопкой отправки. При нажатии ожидается некоторое продолжительное действие, поэтому вы хотите показать пользователю загрузочный gif.

Часть html файла:

    <form>
      <label for="content">Enter value:</label>
      <input id="content" type="text" name="content">
      <button id="submitBtn" type="submit">Send</button>
      <img id="loader" style="display:none" src="../static/img/loading.gif">
    </form>

JS (с использованием jQuery) :


    function sendRequest(content) {
      var payload = {};
      payload.content = content;
      return $.ajax({
        type: 'POST',
        contentType: "application/json",
        url: '/your-endpoint',
        data: JSON.stringify(payload)
      })
    }

    $("#submitBtn").click(function () {
      $('#loader').show();
      $('#submitBtn').prop('disabled', true);
      const response = sendRequest($('#content').val());
      response.then((result) => {
        $('#loader').hide();
        $('#submitBtn').prop('disabled', false);
        $('#content').val("");
        alert(result);
      }).catch(error => {
        $('#loader').hide();
        $('#submitBtn').prop('disabled', false);
        $('#content').val("");
        alert(error);
      });
      return false;
    });

Надеюсь, это поможет.

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