Использование статики в потоках, плохая практика? - PullRequest
0 голосов
/ 06 мая 2018

"Этот вопрос очень часто обсуждается на форумах. Мне лично не нравится" статическое "объявление, поскольку с одной стороны оно подразумевает, что вы можете использовать методы из класса без необходимости объявлять объекты из очень класс, а с другой стороны, прямое совместное использование атрибутов для всех экземпляров класса. Оба поведения, на мой взгляд, являются плохой практикой ООП, но допускаются в JAVA (как и многие другие). " Мой учитель.

Что вы думаете о декларации " static "?

Помимо мнений, которые могут быть у кого-то с этим заявлением, я нахожусь в этой ситуации: Если вы работали с Concurrent Java, вы можете знать, что очень часто можно использовать пример Producer-Consumer.

Следующий код, который я вам показываю, содержит целое число статическое переменная "торт" и статическое объект 'lock' для Синхронизированный блок.

Я думаю, что, очевидно, вопрос заключается в следующем: если использование " static " должно быть (для многих людей) плохой практикой, есть ли альтернативный способ решения подобных проблем без использования " статические"

public class Main implements Runnable {

 private boolean consumer;

 private static int cake=0;

 private static Object lock = new Object();



 public Main (boolean consumer) {

      this.consumer=consumer;

 }



 public void run() {

      while(true) {

            if(consumer) {

                 consume();

            }else {

                 cook();

            }

      }

 }



 private void consume() {

      synchronized(lock) { //Lock

            if(cake>0) { //If there are any cakes...

                 cake--; //Eat a cake.

                 System.out.println("There are "+cake+" pieces of cake left.");

                 try {

                      Thread.sleep(1000);

                 } catch (InterruptedException e) {

                      e.printStackTrace();

                 }

            }else { //If there are no cakes.

                 lock.notifyAll(); //Wake up the cook who was waiting (open Lock, let him cook)

                 try {

                      lock.wait(); //Sleep the consumer (until being awakened)

                 } catch (InterruptedException e) {

                      e.printStackTrace();

                 }

            }

      }

 }



 private void cook() {

      synchronized (lock) {

            if(cake==0) {

                 cake=10; //Cook 10 pieces of cake

                 System.out.println("I'm the cook and there are "+cake+" pieces of cake left.");

                 lock.notifyAll(); //Hey! The cakes are ready! Ok!

            } try {

                 lock.wait(); //sleep the Cook

            }catch(Exception e) {}

      }

 }



 public static void main(String[] args) {

      int threadsNumber = 11;



      Thread[] thread = new Thread[threadsNumber];



      for(int i=0; i<thread.length; i++) {

            Runnable runnable = null;



            if(i !=0) {

                 runnable = new Main(true);

            }else {

                 runnable = new Main(false);

            }



            thread[i] = new Thread(runnable);

            thread[i].start();

      }



      for(int i=0; i<thread.length; i++) {

            try {

                 thread[i].join();

            }catch(Exception e) {}

      }

 }

1 Ответ

0 голосов
/ 06 мая 2018

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

Однако не все статические поля являются " злом " как таковыми. Если вы можете доказать статическое поле и его вложенные зависимости (ссылочный тип) final / неизменяемые или не сохраняющие состояния, то нет ничего плохого в том, чтобы использовать его. Например: -

public class Main implements Runnable{

     private static final int MAXIMUM_CAKE = 100;

     //...the rest of the code.
}

Значение MAXIMUM_CAKE безопасно для совместного использования несколькими потоками. Однако с точки зрения тестирования (покрытия) это было не выгодно, так как ранее было трудно высмеивать статическое поле.

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