为什么输出每次都不同而不是同步块 [英] why output comes different everytime instead of synchronized block

查看:46
本文介绍了为什么输出每次都不同而不是同步块的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

class Callme {
   void call(String msg) {
      System.out.print("[" + msg);
      try {
         Thread.sleep(10);
      } catch (InterruptedException e) {
         System.out.println("Interrupted");
      }
      System.out.println("]");
   }
}


class Caller implements Runnable {
   String msg;
   Callme target;
   Thread t;
   public Caller(Callme targ, String s) {
      target = targ;
      msg = s;
      t = new Thread(this);
      t.start();
      System.out.println("rahul");
      System.out.println("rahul");
      System.out.println("rahul");
      System.out.println("rahul");
      System.out.println("rahul");
      System.out.println("rahul");
      System.out.println("rahul");
      System.out.println("rahul");
      System.out.println("rahul");
      System.out.println("rahul");
   }

   // synchronize calls to call()
   public void run() {
      synchronized(target) { // synchronized block
         target.call(msg);
      }
   }
}

class Synch {
   public static void main(String args[]) {
      Callme target = new Callme();
      Caller ob1 = new Caller(target, "Hello");
      Caller ob2 = new Caller(target, "Synchronized");
      Caller ob3 = new Caller(target, "World");

      // wait for threads to end
      try {
         ob1.t.join();
         ob2.t.join();
         ob3.t.join();
      } catch(InterruptedException e) {
         System.out.println("Interrupted");
      }
   }
}

在这个程序中,当我使用没有 System.out.print("rahul") 的同步块时,它会打印出完美的输出,但是当我把这些不必要的 SOP("rahul") 语句输出时,为什么会发生这种情况而不是同步?

in this program when i use a synchronized block without System.out.print("rahul") it prints perfect output but when i put these unnecessary statement of SOP("rahul") output gets distorted why is it happening instead of synchronization?

推荐答案

我会假设 System.out.println 消息会导致你的 3 个 Caller 消息改变顺序:

I will assume that the System.out.println messages cause your 3 Caller messages to change order:

  Caller ob1 = new Caller(target, "Hello");
  Caller ob2 = new Caller(target, "Synchronized");
  Caller ob3 = new Caller(target, "World");

这里没有保证的顺序.即使 "Hello" Caller 对象首先被构造,这并不意味着它的 run() 方法实际上会首先被执行.每个线程内的 synchronized 块仍然存在竞争.例如,可以先打印 "World" 字符串.

There is no guaranteed order here. Even if the "Hello" Caller object is constructed first, that doesn't mean that its run() method will actually be executed first. There is still a race to the synchronized block inside each of the threads. The "World" string could be printed first for example.

通过添加您的一系列 System.out.println("rahul"); 调用,听起来您正在影响程序的计时.底层的 PrintStream 对象是同步的,因此即使它们正在锁定另一个对象,它也会影响其他线程中的锁定.任何同步都会跨越内存屏障,这会导致线程之间的缓存刷新和内存复制,并可能影响它们的运行顺序、速度等.如果您运行程序 1000 次,您会看到许多不同的输出组合.这就是竞态条件的本质——它们是不可预测的.

By adding your series of System.out.println("rahul"); calls, it sounds like you are affecting the timing of the program. The underlying PrintStream object is synchronized so it will affect the locking in the other threads even if they are locking on another object. Any synchronization crosses a memory barrier which causes cache flushing and memory copying between threads and can affect their run order, speed, etc.. If you ran your program 1000 times you would see many different output combinations. That's the nature of race conditions -- they are unpredictable.

这篇关于为什么输出每次都不同而不是同步块的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆