Page 1 of 1

About Question enthuware.ocpjp.v7.2.1141 :

Posted: Fri Sep 27, 2013 1:37 pm
by Student
"T1 and T2 get two different instances of Student objects."

How are we to know there is more than one Student object in the list? I assumed there was only one.

Re: About Question enthuware.ocpjp.v7.2.1141 :

Posted: Fri Sep 27, 2013 2:17 pm
by admin
You don't have to assume the number of elements in the list to answer this question. You have to answer it assuming that the list could have any number of elements i.e. 0 , 1, or N.

HTH,
Paul.

Re: About Question enthuware.ocpjp.v7.2.1141 :

Posted: Wed Oct 09, 2013 7:17 am
by Student
Okay, I see that now, thanks.

Re: About Question enthuware.ocpjp.v7.2.1141 :

Posted: Fri Oct 11, 2013 10:34 am
by hamada.yamasaki
I don't understand how can we get the reference to the same student object?
Because Student s is local variable and every thread has its own Stack for keeping local variables

Re: About Question enthuware.ocpjp.v7.2.1141 :

Posted: Fri Oct 11, 2013 11:03 am
by admin
hamada.yamasaki wrote:I don't understand how can we get the reference to the same student object?
Because Student s is local variable and every thread has its own Stack for keeping local variables
Yes, s is on the stack but it is pointing to an object, which is on the heap. So that same pointer is being returned from the getStudent() method. That is how multiple threads can get access to the same student objects.

HTH,
Paul.

Re: About Question enthuware.ocpjp.v7.2.1141 :

Posted: Wed Nov 20, 2013 4:36 pm
by jeremy_dd
what if the list contains a Student and a null element ?
like this :
List<Student> l = new ArrayList<Student>();
l.add(new Student());
l.add(null);
System.out.println(l.remove(1)); //prints null
Then option 3 will be correct ?

Re: About Question enthuware.ocpjp.v7.2.1141 :

Posted: Wed Nov 20, 2013 4:56 pm
by admin
The question clearly says, "(Assume that there are no nulls in the list.)"
HTH,
Paul.

Re: About Question enthuware.ocpjp.v7.2.1141 :

Posted: Thu Nov 21, 2013 6:29 am
by jeremy_dd
Oh sorry, didn't pay attention,
thanks
Jeremy

Re: About Question enthuware.ocpjp.v7.2.1141 :

Posted: Mon Feb 01, 2016 8:04 pm
by krohani
Paul - I understand all the answers and the reasoning for the answers however I do have a question.

An ArrayList is backed by an array. If Thread 1 calls remove, isn't the removal of the object a multi-step operation (step 1- Have underlying array point array element to null; step 2- create new smaller array; step 3 - insert elements into new smaller array)?

If the underlying removal of the object is a multi-step operation then why is it not possible that another Thread could come in during these steps and attempt to read or even remove the same element before completion of all underlying steps?

Re: About Question enthuware.ocpjp.v7.2.1141 :

Posted: Mon Feb 01, 2016 9:55 pm
by admin
Yes, it is possible. Why do you think that affects the answer?

Re: About Question enthuware.ocpjp.v7.2.1141 :

Posted: Tue Feb 02, 2016 2:23 pm
by krohani
Because if this scenario can occur then answer choice 3 is also a valid answer choice. In answer choice 3 T1 gets the student object and then the underlying array points this element to null and before it has a chance to resize the array thread T2 attempts to remove the same Student object. When thread T2 does so the student object does not yet exist and the underlying array is pointing to null (as it was still in the middle of the multi-step process) and thread T2 gets null.

Is that possible or am I missing something here?

Re: About Question enthuware.ocpjp.v7.2.1141 :

Posted: Wed Feb 03, 2016 12:51 am
by admin
I think you have a valid point. Your question forced me look into the source code of ArrayList's remove method, but what you are saying doesn't seem possible.
Because if you look at the code, before returning oldValue (which could be null as you pointed out), the code calls System.arraycopy, which will throw an exception either for the first thread or the second thread depending on which one gets to executes later. Therefore, only one of the threads will be able to get a value and the second one will get an exception.

Re: About Question enthuware.ocpjp.v7.2.1141 :

Posted: Wed Feb 03, 2016 1:00 am
by krohani
Okay sounds good. Thank you for the detailed response that helps!

Re: About Question enthuware.ocpjp.v7.2.1141 :

Posted: Wed Jan 11, 2017 12:29 pm
by jagoneye
admin wrote:
hamada.yamasaki wrote:I don't understand how can we get the reference to the same student object?
Because Student s is local variable and every thread has its own Stack for keeping local variables
Yes, s is on the stack but it is pointing to an object, which is on the heap. So that same pointer is being returned from the getStudent() method. That is how multiple threads can get access to the same student objects.

HTH,
Paul.
But how can the same pointer be returned???
I mean even if remove operation is not atomic, still once an object is removed
from the list, then even if the thread gets pre empted before assigning the returned value to String s, now other thread should not be able to obtain the reference to the same object?

Re: About Question enthuware.ocpjp.v7.2.1141 :

Posted: Wed Jan 11, 2017 1:19 pm
by admin
I am not sure I understand what you are saying. Can you show the code along with what you think happens at each line?
Paul.

Re: About Question enthuware.ocpjp.v7.2.1141 :

Posted: Wed Jan 11, 2017 2:01 pm
by jagoneye

Code: Select all


public class ThreadSafety{
  List<Student> sList = new ArrayList<Student>();

  public Student getStudent(){
    Student s = sList.remove(0); <- Here is where I have a doubt
    return s;
  }
  ...other irrelevant code
} 
<- Student s = sList.remove(0);
Since this is an ArrayList and not a ConcurrentList like CopyOnWriteArrayList
hence I understand that the removal operation will not be atomic just like
a "++" or pre-post increment operation is not atomic since it's internally loading and storing values from registers(multistep operation) but what I mean to say is
that once remove() starts it operation and say it removes a student from the list
"S1" even if the first thread gets pre empted before assiging that value to S1

Code: Select all

sList.remove(0);  <-T1 performs this operation and gets prempted
Now there will be no reference to "S1" right? It will be loaded in a register or the operation maybe performed in somewhat similar fashion to "++"
Now when T2 executes

Code: Select all

Student s = sList.remove(0);  <-T2 performs this operation
how does T2 get a reference to "S1" or the same student??
T2 should theoretically get a reference to some other student object or if the List is empty then throw an Exception.
I hope you understand my question.

Re: About Question enthuware.ocpjp.v7.2.1141 :

Posted: Thu Jan 12, 2017 3:26 am
by admin
You need to look inside the code of remove method as well. What if the first thread gets preempted after executing a check inside the remove method but before actually removing the element?

Re: About Question enthuware.ocpjp.v7.2.1141 :

Posted: Thu Jan 12, 2017 5:10 am
by jagoneye
I don't know the internal operations which will be performed during the remove.
I guess what you mean to say is during this operation, when the element is found, it may get pre empted and then before removing the element, the second thread comes in and finds the same element. Thanks for clearing it for me.