1

I have a java program containing a necessary infinite loop. Obviously, just leaving the loop as-is results in the program using the maximum time given to it by the scheduler, so I'd like to yield the current time slice when no more computation can be done for the time.

I've already tried Thread.yield(), Thread.onSpinWait() (Though I'm not sure if that actually does what I think I does), and Thread.sleep(0). All are either ignored 99% of the time, or just don't work.

The one thing that does seem to work is Thread.sleep(x), which drops my cpu usage from ~100% to ~2%. However, sleeping for a set amount of time seems like a bad idea to me. I'm writing a synth at the moment, and so need my time slice back as soon a possible to refill the audio buffer.

I can't simply increase the size of the audio buffer, as doing so quickly introduces extremely noticeable latency.

The audio buffer already spikes to being 80% empty every 20 or so "write cycles", and I'm worried adding a sleep could require too large an audio buffer to avoid artifacts on weaker systems.

Is there any way to consistently yield my current time slice?

the4naves
  • 333
  • 2
  • 9
  • 1
    Can you post a bit more about how you're getting audio into your program? This sounds like having a polling thread, worker thread, and main thread to start both should make the most of your CPU but it's hard to say without knowing more about how data comes in. – kingkupps Jan 25 '20 at 04:30
  • @kingkupps I'm generating the audio myself 512 bytes at a time (Sampling a waveform), and writing those chunks into a SourceDataLine. The infinite loop just does those two things each cycle. – the4naves Jan 25 '20 at 04:37
  • 1
    Thread.yield() yields the time slice, but if there is no other thread to use it, the scheduler will run your thread again; hence 100% – David Zimmerman Jan 25 '20 at 14:48

1 Answers1

4

You could utilize wait & notify to control concurrency.

As your threads are sharing a common resource to exchange data, calling wait on said Object will suspend your Consumer thread until the Producer notifies it, therefore avoiding busy spin.

Reading material:

Julian Durchholz
  • 352
  • 3
  • 12
  • Unfortunately, I don't remove data from the buffer, only add it, so I have no way of doing anything as soon as space becomes available, hence my current code which checks if there is space, and if there is none, sleeps. – the4naves Jan 25 '20 at 20:42