0

I have a few threads running, which are all required to constantly take pictures of different areas of screen. Each thread has its own instance of Robot. The problem is, rather than the shots being taken asynchronously by each thread, they seem to be taken one at a time.

E.g, if I take only one screenshot, it only takes about 20-30 milliseconds. But if I have 5 threads and they all try to take screenshots (of different parts of the screen), then it seems to take 100 - 150 milliseconds to get all 5 screenshots, clearly showing that the shots are being taken synchronously despite the robot.createScreenCapture() method being called from different threads. I want all 5 screenshots to be taken in 20-30 milliseconds.

Is there a way to make robot work asynchronously and send the screenshots to each thread simultaneously? Or a different method of taking screenshots asynchronously which will work in Windows?

Ali
  • 261,656
  • 265
  • 575
  • 769

2 Answers2

2

At least in the OpenJDK implementation, createScreenCapture is synchronized because it's using the underlying OS calls to read the screen buffer directly, so no, it's explicitly impossible to do so. Presumably the underlying graphics primitives either aren't or can't be guaranteed to be reentrant.

chrylis -cautiouslyoptimistic-
  • 75,269
  • 21
  • 115
  • 152
  • @ClickUpvote I presume because at least some window toolkits don't provide an atomic screen-read operation; you'll have to hunt down the source code for the platform implementations of `RobotPeer` for more details. – chrylis -cautiouslyoptimistic- Oct 15 '13 at 00:58
  • I'll be curious to hear if Windows 7 / Windows 8 allows it, and if so, how I can take the screenshot directly using Windows api, without using robot. – Ali Oct 15 '13 at 01:02
  • @ClickUpvote Compositing window managers probably can, but you'd presumably have to use native APIs. – chrylis -cautiouslyoptimistic- Oct 15 '13 at 01:03
  • I'd appreciate any pointers on which API method / module to look into – Ali Oct 15 '13 at 01:13
  • Note that while the method is indeed `synchronized`, it only syncs on the current instance of `Robot`, not between other instances. It has no static-monitor/lock. So maybe it is actually possible by using multiple robots and the lock is just to defend the robots fields from multithreaded access. At least, I think this needs more investigation before a clear conclusion can be made. – Zabuzard May 19 '20 at 14:22
0

I don't agree with the solution.

createScreenCapture is synchronized but you can create two or more instances of the awt robot and use them in a ScheduledExecutorService to have the parallelization needed.

Writing my own screen capture software right now.

Peyman Mohamadpour
  • 17,954
  • 24
  • 89
  • 100
  • Are you sure this increases throughput and that the implementation has no static-synchronization or similar beneath? The current implementation uses a lot of singletons to actually read the screen. So if any of them is synchronized, this likely bottlenecks any attempt to use this multithreaded. – Zabuzard May 19 '20 at 14:20
  • yes, this is the proof of what I said. https://github.com/sblantipodi/JavaFastScreenCapture – sblantipodi May 26 '20 at 09:06