由于system.out.println语句,导致运行线程延迟 [英] Delay in running thread due to system.out.println statement

查看:184
本文介绍了由于system.out.println语句,导致运行线程延迟的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在下面的代码中,如果我在for循环内使用sysout语句,则代码在条件满足后执行并进入循环,但如果我在循环内未使用sysout语句,则无限循环将继续进行,而无需输入if即使满足条件也可以..任何人都可以帮助我找出造成此情况的确切原因.只需sysout语句即可将if条件变为true.为什么会这样呢?

In the following code, if i use sysout statement inside for loop then the code executes and goes inside the loop after the condition met but if i do not use sysout statement inside loop then then infinite loop goes on without entering inside the if condition even if the if condition is satisfied.. can anyone please help me to find out the exact reason for this. Just A sysout statement make the if condition to become true. why is it so?

代码如下:-

class RunnableDemo implements Runnable {
   private Thread t;
   private String threadName;

   RunnableDemo( String name){
       threadName = name;
       System.out.println("Creating " +  threadName );
   }
   public void run() {
      System.out.println("Running " +  threadName );
       for(;;)
       {
           //Output 1: without this sysout statement.
           //Output 2: After uncommenting this sysout statement
           //System.out.println(Thread.currentThread().isInterrupted());
           if(TestThread.i>3)
           {
               try {
                   for(int j = 4; j > 0; j--) {
                       System.out.println("Thread: " + threadName + ", " + j);
                   }
               } catch (Exception e) {
                   System.out.println("Thread " +  threadName + " interrupted.");
               }
               System.out.println("Thread " +  threadName + " exiting.");
           }
       }
   }

   public void start ()
   {
      System.out.println("Starting " +  threadName );
      if (t == null)
      {
         t = new Thread (this, threadName);
         t.start ();
      }

   }

}

public class TestThread {
       static int i=0;
   public static void main(String args[]) {

       RunnableDemo R1 = new RunnableDemo( "Thread-1");
      R1.start();
      try {
        Thread.sleep(10000);
    } catch (InterruptedException e) {

        e.printStackTrace();
    }

    i+=4;
     System.out.println(i);
   }   
}

无限循环中不带sysout语句的输出:- 在此处输入图像描述

在无限循环中使用sysout语句输出:- 在此处输入图片描述

推荐答案

可以通过更改来解决此处的问题

The problem here can be fixed by changing

static int i=0;

static volatile int i=0;

制作变量volatile会带来许多复杂的后果,我不是专家.因此,我将尝试解释我的想法.

Making a variable volatile has a number of complex consequences and I am not an expert at this. So, I'll try to explain how I think about it.

变量i驻留在您的主内存RAM中.但是RAM很慢,因此您的处理器会将其复制到更快(或更小)的内存:缓存中.实际上有多个缓存,但是那无关紧要.

The variable i lives in your main memory, your RAM. But RAM is slow, so your processor copies it to the faster (and smaller) memory: the cache. Multiple caches in fact, but thats irrelevant.

但是,当两个不同处理器上的两个线程将其值放在不同的缓存中时,当值更改时会发生什么?好吧,如果线程1更改了高速缓存1中的值,则线程2仍将使用高速缓存2中的旧值.除非我们告诉两个线程该变量i随时都在变化,就好像它是魔术一样.这就是volatile关键字的作用.

But when two threads on two different processors put their values in different caches, what happens when the value changes? Well, if thread 1 changes the value in cache 1, thread 2 still uses the old value from cache 2. Unless we tell both threads that this variable i might be changing at any time as if it were magic. That's what the volatile keyword does.

那么为什么它可以与print语句一起使用?好吧,print语句在后台调用了许多代码.此代码中的某些很可能包含一个同步块或另一个易失变量,这(偶然)也会刷新两个缓存中的i值. (感谢Marco13指出这一点.)

So why does it work with the print statement? Well, the print statement invokes a lot of code behind the scenes. Some of this code most likely contains a synchronized block or another volatile variable, which (by accident) also refreshes the value of i in both caches. (Thanks to Marco13 for pointing this out).

下次尝试访问i时,您将获得更新的值!

Next time you try to access i, you get the updated value!

PS:我在这里说的是RAM,但它可能是两个线程之间最接近的共享内存,例如,如果它们是超线程的,则可能是缓存.

PS: I'm saying RAM here, but its probably the closest shared memory between the two threads, which could be a cache if they are hyperthreaded for instance.

这也是一个很好的解释(带有图片!):

This is a great explanation too (with pictures!):

http://tutorials.jenkov.com/java-concurrency/volatile.html

这篇关于由于system.out.println语句,导致运行线程延迟的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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