java - Java如何正确添加同步

标签 java multithreading synchronization

当生成整数时,消费者线程将它们的值相加(1+2+3…+10=55)

生产者线程生成 1 到 10 的整数

该程序旨在生成一个整数并立即使用它。但是,程序最后生成的结果很少等于 55。这是因为线程不会等待彼此完成任务

需要在代码中添加同步,以便消费者线程仅在生产者线程生成新整数后才将值添加到总计中

驱动程序.java

    public class Lab08_Driver {

      public static void main(String args[]) {

       UsingSharedInt h = new UsingSharedInt();
       Producer p = new Producer(h);
       Consumer c = new Consumer(h);

        p.start();
        c.start();
      }
    }

消费者.java

  public class Consumer extends Thread {

     private UsingSharedInt cHold;


     public Consumer( UsingSharedInt h )
     {
       super( "ConsumeInteger" );
       cHold = h;
     }

     public void run()
     {
       int val, sum = 0;

       do {
       // sleep for a random interval
       try {
           Thread.sleep( (int) ( Math.random() * 3000 ) );
       }
       catch( InterruptedException e ) {
           System.err.println( e.toString() );
       }

       val = cHold.getSharedInt();
       sum += val;
       } while ( val != 10 );

       System.err.println(
       getName() + " retrieved values totaling: " + sum +
       "\nTerminating " + getName() );
     }
  }

生产者.java

   public class Producer extends Thread {

      private UsingSharedInt pHold;

      public Producer( UsingSharedInt h )
      {
         super( "ProduceInteger" );
         pHold = h;
      }

      public void run()
      {
          for ( int count = 1; count <= 10; count++ ) {
          // sleep for a random interval
          try {
              Thread.sleep( (int) ( Math.random() * 3000 ) );
          }
          catch( InterruptedException e ) {
              System.err.println( e.toString() );
          }

         pHold.setSharedInt( count );
       }

       System.err.println( getName() +
       " finished producing values" +
       "\nTerminating " + getName() );
     }
   }

使用SharedInt.java

    // HoldIntegerUnsynchronized.java

    public class UsingSharedInt {

       private int sharedInt = -1;

       public void setSharedInt( int val )
       {
          System.err.println( Thread.currentThread().getName() +
          " setting sharedInt to " + val );
          sharedInt = val;
       }

       public int getSharedInt()
       {
         System.err.println( Thread.currentThread().getName() +
         " retrieving sharedInt value " + sharedInt );
         return sharedInt;
       }
   }

最佳答案

只需使用BlockingQueue作为生产者生产和消费者消费的元素的容器:

public class UsingSharedInt {

       private BlockingQueue<Integer> q = new ArrayBlockingQueue<>(100);

       public void setSharedInt( int val )
       {
          System.err.println( Thread.currentThread().getName() +
          " setting sharedInt to " + val );
          q.add(val); // puts val into the queue
       }

       public int getSharedInt()
       {
         int val = q.take(); // waits for element to become available in queue, then returns one
         System.err.println( Thread.currentThread().getName() +
         " retrieving sharedInt value " + val);
         return val;
       }
   }

关于java - Java如何正确添加同步,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/60333467/

相关文章:

c - 多请求单响应同步

java - android:如何从用户定义的类访问 UI 对象

c# - 高频计时.NET

java - UCanAccess:打开和关闭必填字段以防止违反完整性约束:NOT NULL 错误

java 正则表达式 yyyyMMdd 中 1900-9999 的日期验证

c++ - fork() 除了执行外部程序之外的用处

java - 此类中引用的 Map 是否安全发布?

java - 同步块(synchronized block)是否会阻止其他线程访问对象?

java - 使用已弃用的 glTranslatef 还是使用 glBufferSubData 更新坐标更好?

java - 我如何在 Java 中创建一个能够更改其自身源代码或随后运行的数学函数的程序?