• Post Reply Bookmark Topic Watch Topic
  • New Topic
programming forums Java Mobile Certification Databases Caching Books Engineering Micro Controllers OS Languages Paradigms IDEs Build Tools Frameworks Application Servers Open Source This Site Careers Other Pie Elite all forums
this forum made possible by our volunteer staff, including ...
Marshals:
  • Campbell Ritchie
  • Ron McLeod
  • Rob Spoor
  • Tim Cooke
  • Junilu Lacar
Sheriffs:
  • Henry Wong
  • Liutauras Vilda
  • Jeanne Boyarsky
Saloon Keepers:
  • Jesse Silverman
  • Tim Holloway
  • Stephan van Hulst
  • Tim Moores
  • Carey Brown
Bartenders:
  • Al Hobbs
  • Mikalai Zaikin
  • Piet Souris

Sybex OCP Java 8 Study Guide

 
Greenhorn
Posts: 2
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Hi,
In my opinion Chapter 7 Question #17 has incorrect answer (according to java memory model).
The Appendix A refers to B (it outputs 100 100) as correct answer. In my opinion C is correct answer (The output cannot be determined ahead of time).
The question has
private static int sheepCount2 =0;
and it is incremented inside newSingleThreadExecutor.
We have 2 threads
T1 - main application thread
T2 - thread from singleThreadExecutor.

There is no happen before relation between T1 and T2 to read the sheepCount2 by T1 after modifications from T2.

Java doc for java.util.concurrent.ExecutorService
"Actions in a thread prior to the submission of a Runnable or Callable task to an ExecutorService happen-before any actions taken by that task"
this guarantee the visibility of initial value of sheepCount2 inside T2
T2 will modify sheepCount2
We wait 100ms - no impact on data visibility

And T1 will read sheepCount2 - System.out.println(sheepCount2). T1 has no guarantee to have update value from T2 modifications
or rephrasing  T1 will access sheepCount2 without happen before relation with T2.

We need to have a volatile/AtomicInteger on sheepCount or use future with get().
'any actions taken by that task ... happen-before the result is retrieved via Future.get().'
 
author
Posts: 4278
34
jQuery Eclipse IDE Java
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
First off, thanks for your feedback.  I’ve reviewed it and don’t spot any errata here.  Did you try executing the code?  The ExecutorService has only one thread, so everything happens in serial.  Also, did you read the statement at the start of the question?

“Assuming 100 milliseconds is enough time for the tasks submitted to the thread executor to complete, what is the result of executing the following program?”

There is more than enough time for the threads submitted to the executor to finish and output 100 100.
 
Andrzej Czarny
Greenhorn
Posts: 2
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Hi Scott
I will try to describe it using happens before order.
To simplify lets assume that the main thread will add all 100 Runnables to executor before executor starts executing. We can also assume that it is multi core machine where the main application thread is executed on cpu1 and the executor thread is on cpu2

main thread - cpu1happens before orderexecutor thread - cpu2cpu1  sheepCount1, sheepCount2cpu2  sheepCount1, sheepCount1
service.execute(....)0, 0initial value, initial value
...............
service.execute(....)0, 0initial value, initial value  
Actions in a thread prior to the submission of a Runnable to an Executor happen-before its execution begins0, 00, 0
Thread.sleep(100);sheepCount1.getAndIncrement(); sheepCount2++;0, 01, 1
...............
sheepCount1.getAndIncrement(); sheepCount2++;0, 099, 99
sheepCount1.getAndIncrement(); sheepCount2++;0, 0100, 100
System.out.println(
sheepCount1+" "sheepcount1.get() happens before any other set or updates (Ordering of write and read actions on volatile) we will have 100  100, 99100, 100
+sheepCount2)sheepCount2 has no happens before order100, 99100, 100

The 100 on sheepCount2 does not have to be visible on the main thread (cpu1) as it is executed after getAndIncrement on (cpu2) and the store buffer does not have to be synchronized with other cores caches as it is just plain variable.
To fix the problem all you have to do is to revert the order of Runnable ()-> {sheepCount1.getAndIncrement(); sheepCount2++};
to  ()-> {sheepCount2++; sheepCount1.getAndIncrement()};
Now visibility of sheepCount2++ is guranted by happens before order between writing to sheepCount1 and reading sheepCount1. Or event simpler change sheepCount2 to AtomicInteger.
I will agree that it is very unlike to hit the 99 but still the answer is incorrect as 100, 99 is possible result.

The problem is similar to my puzzle with jcstress where 3 is still possible

result


 Observed state   Occurrences   Expectation  Interpretation                                              
              1   111,112,823    ACCEPTABLE  Actor2 is executed before Actor1                            
              2        33,631    ACCEPTABLE  Actor2 is executed after y = 2 and before x = 3 in Actor1  
              3        26,441     FORBIDDEN  y = 2 can not be reordered with x = 3 as we have volatile...
              6    21,031,593    ACCEPTABLE  Actor2 executed after Actor1                                


to fix it you have to revert y*x to x*y to have happens before order between writing to volatile x and reading it


 Observed state   Occurrences   Expectation  Interpretation                                              
              1   119,613,062    ACCEPTABLE  Actor2 is executed before Actor1                            
              2       134,699    ACCEPTABLE  Actor2 is executed after y = 2 and before x = 3 in Actor1  
              3             0     FORBIDDEN  y = 2 can not be reordered with x = 3 as we have volatile...
              6    32,083,827    ACCEPTABLE  Actor2 executed after Actor1                                



What is your opinion?
 
You showed up just in time for the waffles! And this tiny ad:
Building a Better World in your Backyard by Paul Wheaton and Shawn Klassen-Koop
https://coderanch.com/wiki/718759/books/Building-World-Backyard-Paul-Wheaton
reply
    Bookmark Topic Watch Topic
  • New Topic