使用"静态"在线程,糟糕的做法?

时间:2018-05-06 14:38:09

标签: java multithreading static declaration

"这是一个在论坛中处理的问题。我个人不喜欢"静电"声明,因为它一方面暗示你可以使用类中的方法,而不需要从类中声明对象,另一方面直接共享类的所有实例的属性。 在我看来,这两种行为都是OOP的不良行为,但在JAVA中允许(与许多其他事情一样)。" 我的老师。

您如何看待" 静态"声明?

除了任何人对此声明可能有的意见外,我处于这种情况: 如果你已经处理过Concurrent Java,你可能会知道使用Producer-Consumer的例子很常见。

我向您展示的以下代码包含整数静态变量" cake" 静态 '锁定' 同步块的对象。

我认为显然问题是:如果使用" 静态"应该是(对许多人来说)一个不好的做法,有没有其他方法来解决这些问题而不使用" 静态"?

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 :(得分:0)

如果静态字段在线程之间是可变的并且是共享的,则需要读取和写入同步以确保每个线程对正确和更新的值进行操作。

然而,并非每个静态字段本身都是“ evil ”。如果你可以证明一个静态字段,并且它的嵌套依赖项(引用类型)是final / immutable或无状态,那么使用它没有任何错误。例如: -

public class Main implements Runnable{

     private static final int MAXIMUM_CAKE = 100;

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

MAXIMUM_CAKE值可由多个线程共享。然而,在测试视角(覆盖范围)上,它不利于以前很难模拟静态场。