繁体   English   中英

Java中的线程同步

[英]Threads synchronization in Java

我有一个类似的场景。...有四个线程分别命名为Thread1,Thread2,Thread3和Thread4。 并且有一个计数器变量。 我想输出如下

Thread1 : value of counter variable is = 0
Thread2 : value of counter variable is = 1
Thread3 : value of counter variable is = 2
Thread4 : value of counter variable is = 3

Thread1 : value of counter variable is = 4
Thread2 : value of counter variable is = 5
Thread3 : value of counter variable is = 6
Thread4 : value of counter variable is = 7

Thread1 : value of counter variable is = 8
Thread2 : value of counter variable is = 9
Thread3 : value of counter variable is = 10
Thread4 : value of counter variable is = 11

甚至我在逻辑上也做到了。 但是我想要类似的东西,当Thread1正在打印counter变量时,所有其余线程都应等待.....然后在Thread2之后出现图片并打印counter变量,其余应等待。

建议我为此的最佳解决方案。 提前致谢 :-)

除了了解同步,这几乎没有意义。 我会使用CyclicBarrier来做到这一点。 这是一个相当高级的抽象,因此您不必自己使用wait()notifiy()

或者,您可以使用IntegerAtomicInteger对象作为变量,并将其传递到线程周围(每个对象都应提供可被另一个线程调用的consume(Integer i)方法,然后递增并打印该值并将其传递给下一个螺纹)。 在此变体中,同步在代码中隐式处理。

我不确定你想要什么。 您是否要让线程按顺序增加并打印变量? 这没有任何意义,线程是独立的,并且可以同时运行。 那就是他们的目的。

因此,让我直接讲:您想使用并行处理来进行串行工作。

基本上,您要做的是:

for(int i=0;i<10;i++)
    System.out.println(i);

但是然后有线程。

线程用于并行处理事务。 那就是他们的目的。 试图将串行问题强加给这个概念,不仅会减慢您的应用程序的速度,而且会使它更容易出错。

当然,除非您的这个示例非常简化。 也许您需要提供更多信息以帮助我们,然后...

这是一个有趣的问题,因为线程被设计为独立地并排工作,而不是严格地锁定在一起。

我认为最简单的方法是使用公平的ReentrantLockAtomicInteger和一些谨慎的设置(以确保线程以正确的顺序开始在ReentrantLock上等待)。

您的主线程将需要初始化计数器,创建锁对象并对其进行锁定,然后依次启动四个子线程,确保在关闭下一个线程之前,每个子线程都到达了锁。

当所有4个线程准备就绪时,您可以释放锁并让其他线程运行。

每个工作线程应从计数器中获取值,将其递增,显示计数器,然后释放锁(这将使下一个线程运行),然后再重新获取它。

请注意,这里仍然存在竞争条件:线程2可能在线程1开始再次等待锁之前绕循环运行,因此这两个线程最终将以相反的顺序运行。 要解决此问题,辅助线程需要等待,直到有足够多其他线程在等待,直到它们在循环中继续进行为止(当然,最后一次迭代除外)。 不太好,但是由于列出的限制,我担心这很重要。

这不是简单的代码。 我认为,这里要学习的教训是,您不应该真正使用多个线程来执行固有的串行工作! 要么,要么您不必在乎哪个线程执行哪个串行操作。

我找到了解决此问题的两种方法。...但仍在等待专家评论...。

第一种方式:-----

包semafore;

导入java.util.concurrent.Semaphore;

公共类Main {公共静态void main(String args [])引发异常{Semaphore sem = new Semaphore(1,true); 线程thrdA = new Thread(new SyncOutput(sem,“ Thread1”)); 线程thrdB = new Thread(new SyncOutput(sem,“ Thread2”)); 线程thrdC =新线程(新SyncOutput(sem,“ Thread3”)); 线程thrdD =新线程(新SyncOutput(sem,“ Thread4”));

    thrdA.start();
    thrdB.start();
    thrdC.start();
    thrdD.start();

    thrdA.join();
    thrdB.join();
    thrdC.join();
    thrdD.join();

}

}

SyncOutput类实现Runnable {Semaphore sem; 字符串味精; 私有静态int val = 0;

SyncOutput(Semaphore s, String m) {
    sem = s;
    msg = m;
}

public void run() {
    for (int i = 0; i < 3; i++){
        try {
            sem.acquire(1);
            System.out.println(msg + " : " + ++val);
            Thread.sleep(1000);
        } catch (Exception exc) {
            System.out.println("Error Writing File");
        }
    sem.release(1);
    }
}

}

第二种方式:-----

包线程;

 class num {
         // state variable identifying whose turn it is.
         private String whoseTurn ="A";
         private int cnt=0;

  public  boolean writenum(String who) {

           String x = Thread.currentThread().getName();
                try{
                    Thread.sleep(1000);
                }catch(Exception e){}
          if (x.equalsIgnoreCase(whoseTurn)) {
              System.out.println(x+":"+cnt++);
              if(x.equalsIgnoreCase("A"))
                whoseTurn = "B";
              else if(x.equalsIgnoreCase("B"))
                    whoseTurn = "C";
              else if( x.equalsIgnoreCase("C"))
                    whoseTurn = "D";
              else if( x.equalsIgnoreCase("D"))
                    whoseTurn = "A";

          }
          return true; 
     }
  }


public class Game {

    public static void main(String args[]) {
        num ob = new num();
        Thread A = new Thread(new Player("A", ob));
         Thread B   = new Thread(new Player("B", ob));
        Thread C   = new Thread(new Player("C", ob));
        Thread D   = new Thread(new Player("D", ob));

    A.setName("A");
    B.setName("B");
    C.setName("C");
    D.setName("D");
   A.start();   
   B.start();  
   C.start();
   D.start();
   try {
       // Wait 5 seconds
       Thread.currentThread().sleep(5000);
   } catch (InterruptedException e) { }

   ob.writenum("DONE"); // cause the players to quit their threads.
   try {
       Thread.currentThread().sleep(100);
   } catch (InterruptedException e) { }
   }

}

class Player implements Runnable {
       num area;   // Table where they play
       String who;

       public Player(String who, num area) {
           this.area  = area;
          this.who = who;
       }

      public void run() {
      while (area.writenum(who));

      }
  }

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM