Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]


Groups > comp.lang.java.programmer > #31314 > unrolled thread

VERY PECULIAR PROBLEM

Started byDoug Mika <dougmmika@gmail.com>
First post2015-03-12 11:38 -0700
Last post2015-03-13 21:40 +0100
Articles 7 — 6 participants

Back to article view | Back to comp.lang.java.programmer


Contents

  VERY PECULIAR PROBLEM Doug Mika <dougmmika@gmail.com> - 2015-03-12 11:38 -0700
    Re: VERY PECULIAR PROBLEM Eric Sosman <esosman@comcast-dot-net.invalid> - 2015-03-12 14:57 -0400
    Re: VERY PECULIAR PROBLEM Robbie Brown <rob@example.com> - 2015-03-12 19:29 +0000
    Re: VERY PECULIAR PROBLEM Joshua Cranmer 🐧 <Pidgeot18@verizon.invalid> - 2015-03-12 22:52 -0500
    Re: VERY PECULIAR PROBLEM Nigel Wade <nmw@ion.le.ac.uk> - 2015-03-13 09:36 +0000
      Re: VERY PECULIAR PROBLEM Robbie Brown <rob@example.com> - 2015-03-13 10:12 +0000
        Re: VERY PECULIAR PROBLEM Robert Klemme <shortcutter@googlemail.com> - 2015-03-13 21:40 +0100

#31314 — VERY PECULIAR PROBLEM

FromDoug Mika <dougmmika@gmail.com>
Date2015-03-12 11:38 -0700
SubjectVERY PECULIAR PROBLEM
Message-ID<f9da1c67-a91e-4ec6-8199-137af1736453@googlegroups.com>
Hi to all, I don't know what is wrong with the following method.  It is a method inside a Timer class that extends Thread.  The peculiar problem is that IF i include the System.out.print(""); line in the method, the program works FINE, if however I delete the System.out.print(""); methods or REM it out, the program doesn't count time?  How Could that one line which does NOTHING cause the entire program to function correctly?

 public void run(){
        long timeStamp = System.currentTimeMillis();
        
        while(true){
            if(timeStamp + 1000 <= System.currentTimeMillis()){
                timeStamp = System.currentTimeMillis();
                
                System.out.print("");
                if(this.paused==false){
                    this.secCount++;
                    
                    this.hrs = (int)this.secCount / 3600;
                    this.min = (int)(((int)(this.secCount % 3600))/60);
                    this.sec = (int)this.secCount % 60;
                    
                    if(this.debug) System.out.println("Timer: "+this.hrs+":"+this.min+":"+this.sec);
                }
            }
        }
    }

Much thanks for any ideas, I have NO IDEA why a System.out.print statement could impact the functioning of this program to such an extent?
Doug

[toc] | [next] | [standalone]


#31315

FromEric Sosman <esosman@comcast-dot-net.invalid>
Date2015-03-12 14:57 -0400
Message-ID<mdsnhv$pjp$1@dont-email.me>
In reply to#31314
On 3/12/2015 2:38 PM, Doug Mika wrote:
> Hi to all, I don't know what is wrong with the following method.  It is a method inside a Timer class that extends Thread.  The peculiar problem is that IF i include the System.out.print(""); line in the method, the program works FINE, if however I delete the System.out.print(""); methods or REM it out, the program doesn't count time?  How Could that one line which does NOTHING cause the entire program to function correctly?
>
>   public void run(){
>          long timeStamp = System.currentTimeMillis();
>
>          while(true){
>              if(timeStamp + 1000 <= System.currentTimeMillis()){
>                  timeStamp = System.currentTimeMillis();
>
>                  System.out.print("");
>                  if(this.paused==false){
>                      this.secCount++;
>
>                      this.hrs = (int)this.secCount / 3600;
>                      this.min = (int)(((int)(this.secCount % 3600))/60);
>                      this.sec = (int)this.secCount % 60;
>
>                      if(this.debug) System.out.println("Timer: "+this.hrs+":"+this.min+":"+this.sec);
>                  }
>              }
>          }
>      }
>
> Much thanks for any ideas, I have NO IDEA why a System.out.print statement could impact the functioning of this program to such an extent?

     Neither do I?  Also, I have NO IDEA what the rest of the code
looks like?  And I don't know how you determined that it "doesn't
count time?"

     Perhaps if you were to post an SSCCE (see <http://www.sscce.org/>),
either I or someone else might be able to help?

-- 
esosman@comcast-dot-net.invalid
"Don't be afraid of work. Make work afraid of you." -- TLM

[toc] | [prev] | [next] | [standalone]


#31316

FromRobbie Brown <rob@example.com>
Date2015-03-12 19:29 +0000
Message-ID<mdspdo$1pu$1@dont-email.me>
In reply to#31314
On 12/03/15 18:38, Doug Mika wrote:
> Hi to all, I don't know what is wrong with the following method.  It is a method inside a Timer class that extends Thread.  The peculiar problem is that IF i include the System.out.print(""); line in the method, the program works FINE, if however I delete the System.out.print(""); methods or REM it out, the program doesn't count time?  How Could that one line which does NOTHING cause the entire program to function correctly?
>
>   public void run(){
>          long timeStamp = System.currentTimeMillis();
>
>          while(true){
>              if(timeStamp + 1000 <= System.currentTimeMillis()){
>                  timeStamp = System.currentTimeMillis();
>
>                  System.out.print("");
>                  if(this.paused==false){
>                      this.secCount++;
>
>                      this.hrs = (int)this.secCount / 3600;
>                      this.min = (int)(((int)(this.secCount % 3600))/60);
>                      this.sec = (int)this.secCount % 60;
>
>                      if(this.debug) System.out.println("Timer: "+this.hrs+":"+this.min+":"+this.sec);
>                  }
>              }
>          }
>      }
>
> Much thanks for any ideas, I have NO IDEA why a System.out.print statement could impact the functioning of this program to such an extent?
> Doug
>

Hmm, I just wrapped your code in a *simple* test class and ran it, it 
produces output with or without the System.out, I think you should be 
looking elsewhere.

package com.foo;

public class TimerTest extends Thread{
	
	int hrs, min, sec, secCount;
	boolean debug = true;
	boolean paused = false;
	
	public void run(){
         long timeStamp = System.currentTimeMillis();

         while(true){
             if(timeStamp + 1000 <= System.currentTimeMillis()){
                 timeStamp = System.currentTimeMillis();

                 //System.out.print("");
                 if(this.paused==false){
                     this.secCount++;

                     this.hrs = (int)this.secCount / 3600;
                     this.min = (int)(((int)(this.secCount % 3600))/60);
                     this.sec = (int)this.secCount % 60;

                     if(this.debug) System.out.println("Timer: 
"+this.hrs+":"+this.min+":"+this.sec);
                 }
             }
         }
     }
	
	public static void main(String[] args){
		new TimerTest().start();
	}

}

//output

Timer: 0:0:1
Timer: 0:0:2
Timer: 0:0:3
Timer: 0:0:4
Timer: 0:0:5
Timer: 0:0:6
Timer: 0:0:7
... etc


-- 
Not floundering ... just fishing

[toc] | [prev] | [next] | [standalone]


#31317

FromJoshua Cranmer 🐧 <Pidgeot18@verizon.invalid>
Date2015-03-12 22:52 -0500
Message-ID<mdtmt9$3te$1@dont-email.me>
In reply to#31314
On 3/12/2015 1:38 PM, Doug Mika wrote:
> Hi to all, I don't know what is wrong with the following method.  It
> is a method inside a Timer class that extends Thread.  The peculiar
> problem is that IF i include the System.out.print(""); line in the
> method, the program works FINE, if however I delete the
> System.out.print(""); methods or REM it out, the program doesn't
> count time?  How Could that one line which does NOTHING cause the
> entire program to function correctly?

I don't know. Your test case contains insufficient details to let us do 
anything else other than wildly guess at what your code is doing. For 
all I know, it's supposed to be training a hyena to chew off your balls 
and it's instead training it to chew off your nose.

More seriously though, despite the almost total lack of information, I'm 
going to guess that the problem is that paused (and probably secCount 
too, come to think of it) is not declared in the class to be a volatile 
variable. That, or some sort of lack of synchronization (of which 
volatile is a form of synchronization, but I digress), or possibly a 
timing issue.

To answer your "how" question (which is still instructive even if my 
guess is completely wrong), the JIT compiler is free to do whatever it 
wants so long as it preserves observable behavior. In this case, the 
compiler would see an infinite loop and variables that are written to 
but never read. If the variables are not declared volatile, then there 
is no guarantee that they will ever be read or written to if accessed 
from multiple threads unless you provide some sort of synchronization. A 
call to System.out.print very possibly could cause that sort of 
synchronization, at least as far as the compiler knows.

-- 
Beware of bugs in the above code; I have only proved it correct, not
tried it. -- Donald E. Knuth

[toc] | [prev] | [next] | [standalone]


#31318

FromNigel Wade <nmw@ion.le.ac.uk>
Date2015-03-13 09:36 +0000
Message-ID<cmfpdgFircbU1@mid.individual.net>
In reply to#31314
My guess, and it has to be a guess because of the total lack of information as others have highlighted, is that your 
code (the *other* code, which you don't show) "doesn't count time" because it's running in another thread which isn't 
synchronized properly. The code you've shown is a tight, CPU bound, loop so I guess the other thread is starved of CPU 
cycles. Add your System.out and the tight loop becomes I/O bound, allowing the other thread to gain CPU cycles.

All complete conjecture based on a complete lack of information.

[toc] | [prev] | [next] | [standalone]


#31319

FromRobbie Brown <rob@example.com>
Date2015-03-13 10:12 +0000
Message-ID<mdud5d$24m$1@dont-email.me>
In reply to#31318
On 13/03/15 09:36, Nigel Wade wrote:
> My guess, and it has to be a guess because of the total lack of
> information as others have highlighted, is that your code (the *other*
> code, which you don't show) "doesn't count time" because it's running in
> another thread which isn't synchronized properly. The code you've shown
> is a tight, CPU bound, loop so I guess the other thread is starved of
> CPU cycles. Add your System.out and the tight loop becomes I/O bound,
> allowing the other thread to gain CPU cycles.
>
> All complete conjecture based on a complete lack of information.

This sounds highly plausible.

I'll probably get shouted at for suggesting this but WTF.

OP why don't you paste-bin your code and let the boffins (and us that 
are less than perfect) have a look.

Just a suggestion

-- 
Not floundering ... just fishing

[toc] | [prev] | [next] | [standalone]


#31320

FromRobert Klemme <shortcutter@googlemail.com>
Date2015-03-13 21:40 +0100
Message-ID<cmh09tFt05oU1@mid.individual.net>
In reply to#31319
On 13.03.2015 11:12, Robbie Brown wrote:
> On 13/03/15 09:36, Nigel Wade wrote:
>> My guess, and it has to be a guess because of the total lack of
>> information as others have highlighted, is that your code (the *other*
>> code, which you don't show) "doesn't count time" because it's running in
>> another thread which isn't synchronized properly. The code you've shown
>> is a tight, CPU bound, loop so I guess the other thread is starved of
>> CPU cycles. Add your System.out and the tight loop becomes I/O bound,
>> allowing the other thread to gain CPU cycles.
>>
>> All complete conjecture based on a complete lack of information.
>
> This sounds highly plausible.

CPU starvation is not so likely on modern hardware and OS.  I think it 
more plausible that, since writing to the stream is missing (which is 
synchronized!), there is no memory barrier and updates on non volatile 
variables in the measurement thread are not visible to whatever other 
thread tries to get at the timing measurement.

> OP why don't you paste-bin your code and let the boffins (and us that
> are less than perfect) have a look.

Amen.  There is really far too little information.

Cheer

	robert

-- 
remember.guy do |as, often| as.you_can - without end
http://blog.rubybestpractices.com/

[toc] | [prev] | [standalone]


Back to top | Article view | comp.lang.java.programmer


csiph-web