I would like to know what this tutorial means when it refers to the following bit of explanation. In particular the part which I highlighted in bold.
Insert
The addfirst and offerFirst methods insert elements at the beginning
of the Deque instance. The methods addLast and offerLast insert
elements at the end of the Deque instance. When the capacity of the
Deque instance is restricted, the preferred methods are offerFirst and
offerLast because addFirst might fail to throw an exception if it is
full.
Why would offerFirst be preferred?
Why would addFirst fail to throw an exception if it is full? Should not it be better if it guaranteed to throw an exception in those circumstances?
I think both methods are legitimate (though the offerXXX methods are more likely to be used in bounded dequeues).
If your code assumes that there's available space in the queue, and this assumption is critical to the correctness of the code, use addFirst/addLast. The runtime exception being thrown (IllegalStateException) is perfectly suitable for this bug scenario.
If, on the other hand, a full queue is a normal scenario, don't deal with it using exceptions. Use offerFirst/offerLast, and check the returned value.
OfferFirst is the prefereable methods if there is a risk the deque will reach capacity. If it has reached capacity addFirst will throw an exception, where as offerFirst returns a boolean (true/false) value to indicate if the add was successful. offerFirst Inserts the specified element at the front of this deque unless it would violate capacity restrictions. When using a capacity-restricted deque, this method is generally preferable to the addFirst(E) method, which can fail to insert an element only by throwing an exception.
Why would be that when using the restricted version you would not want an exception thrown when adding the element fails. This is because you would expect some failures which is why you are offering to add instead of insisting to add.
It means that the offerXXX methods return boolean, and the addXXX methods don't.
So it is recommending that you use offerXXX and check the boolean for success, rather than expecting an exception to be thrown from either method.
It's very badly worded. And so is the Javadoc.
According to Docs:
offerFirst:
Inserts the specified element at the front of this deque unless it would violate capacity restrictions. When using a capacity-restricted deque, this method is generally preferable to the addFirst(E) method, which can fail to insert an element only by throwing an exception.
Which means if you use addFirst with a capacity restricted deque, it may throw an exception, but using offerFirst won't throw any exception.
offerLast
Inserts the specified element at the end of this deque unless it would violate capacity restrictions. When using a capacity-restricted deque, this method is generally preferable to the addLast(E) method, which can fail to insert an element only by throwing an exception.
Similarly if you use addLast with a capacity restricted deque, it may throw an exception, but using offerLast won't throw any exception.
Related
Below is the code, I am getting a ConcurrentModificationException in the subiter.next() call even though I am not modifying the underlying collection and its running as a single thread.
Tree tree=partition.getTreeofThisPartition();
Set<DzExpressionHostTupel> oldSubtupels=tree.getSubscribers();
Iterator<DzExpressionHostTupel> subiter=oldSubtupels.iterator();
while (subiter.hasNext()){
DzExpressionHostTupel subtupel=subiter.next();
tree.removeSubscriber(subtupel);
}
If you read https://docs.oracle.com/javase/7/docs/api/java/util/ConcurrentModificationException.html, it says:
For example, it is not generally permissible for one thread to modify a Collection while another thread is iterating over it. In general, the results of the iteration are undefined under these circumstances. Some Iterator implementations (including those of all the general purpose collection implementations provided by the JRE) may choose to throw this exception if this behavior is detected. Iterators that do this are known as fail-fast iterators, as they fail quickly and cleanly, rather that risking arbitrary, non-deterministic behavior at an undetermined time in the future.
Note that this exception does not always indicate that an object has been concurrently modified by a different thread. If a single thread issues a sequence of method invocations that violates the contract of an object, the object may throw this exception. For example, if a thread modifies a collection directly while it is iterating over the collection with a fail-fast iterator, the iterator will throw this exception.
(emphasis added).
I'm guessing tree.removeSubscriber(subtupel); is modifying its subscribers set.
Imagine the following scenario:
I have a standard Java ArrayList<String>.
This ArrayList<String> is accessed by multiple threads with no explicit synchronisation, subject to the following constraints:
Multiple reads may occur at the same time (possibly concurrent with the write described below). All reads call the iterator() method on the ArrayList<String> and exclusively use the returned Iterator<E> (iterators are not shared between threads). The only methods called on the Iterator<String> are hasNext() and next() (the remove() method is not called).
One thread may write to the list (possibly concurrent with reads but not concurrent with other writes). Each write only calls the add(String) and remove(Object) methods on the ArrayList<E>.
I know the follow to be true:
The read threads may see outdated data.
The read threads may experience a ConcurrentModificationException.
Apart from the above two problems, can anything else go wrong?
I am looking for specific examples (of the form, if x and y are true, then z will occur, where z is bad). It has to be something that can actually happen in practice. Please provide citations where possible.
(I personally think that other failures are possible but I have been challenged to come up with specific examples of why the above scenario is not suitable for production code.)
I would expect that your readers or your writer could get an ArrayIndexOutOfBounds exception or a null pointer exception, as well, since they can be seeing inconsistent state of the underlying array.
You really are at the mercy of the detailed implementation of the ArrayList class-- which can vary from environment to environment. It is possible that the JVM could implement the class with native code that could cause worse undefined behavior (JVM crash) when reading without synchronization.
I'll add this from the text of the ConcurrentModificationException reference page:
Note that fail-fast behavior cannot be guaranteed as it is, generally speaking, impossible to make any hard guarantees in the presence of unsynchronized concurrent modification. Fail-fast operations throw ConcurrentModificationException on a best-effort basis. Therefore, it would be wrong to write a program that depended on this exception for its correctness: ConcurrentModificationException should be used only to detect bugs.
In short, you can't depend on nothing bad happening besides stale data and ConcurrentModificationException.
I have no idea why a ConcurrentModificationException occurs when i iterate over an ArrayList. The ArrayList is methode scoped, so it should not be visible by other threads which execute the same code. At least if i understodd multi threading and variable scopes correctly.
Caused by: java.util.ConcurrentModificationException
at java.util.AbstractList$SimpleListIterator.next(AbstractList.java:64)
at com....StrategyHandler.applyStrategy(StrategyHandler.java:184)
private List<Order> applyStrategy(StorageObjectTree storageObjectTree) {
...
List<OrderHeader> finalList = new ArrayList<Order>();
for (StorageObject storageObject : storageObjectTree.getStorageObjects()) {
List<Order> currentOrders = strategy.process(storageObject);
...
if (currentOrders != null) {
Iterator<Order> iterator = currentOrders.iterator();
while (iterator.hasNext()) {
Order order = (Order) iterator.next(); // line 64
// read some values from order
}
finalList.addAll(currentOrders);
}
}
return finalList;
}
Can anybody give me an hint what could be the source of the problem?
If You have read the Java Doc for ConcurrentModifcationException :
It clearly states the condition in which it occurs:
This exception may be thrown by methods that have detected concurrent
modification of an object when such modification is not permissible.
For example, it is not generally permissible for one thread to modify
a Collection while another thread is iterating over it. In general,
the results of the iteration are undefined under these circumstances.
Some Iterator implementations (including those of all the general
purpose collection implementations provided by the JRE) may choose to
throw this exception if this behavior is detected. Iterators that do
this are known as fail-fast iterators, as they fail quickly and
cleanly, rather that risking arbitrary, non-deterministic behavior at
an undetermined time in the future.
Note that this exception does not always indicate that an object has
been concurrently modified by a different thread. If a single thread
issues a sequence of method invocations that violates the contract of
an object, the object may throw this exception. For example, if a
thread modifies a collection directly while it is iterating over the
collection with a fail-fast iterator, the iterator will throw this
exception.
Note that fail-fast behavior cannot be guaranteed as it is, generally
speaking, impossible to make any hard guarantees in the presence of
unsynchronized concurrent modification. Fail-fast operations throw
ConcurrentModificationException on a best-effort basis. Therefore, it
would be wrong to write a program that depended on this exception for
its correctness: ConcurrentModificationException should be used only
to detect bugs.
In your case as you said, you do not have multiple threads accessing this list. it might still be possible as per second paragraph above if your single thread that is reading from iterator might be trying to write to it as well.
Hope this helps.
This exception occurred when you changing/adding/removing values from your list and in the same time you are iterating it. And if you use many threads at the same time...
Try to surround your if by synchronized(currentOrders) { /* YOUR LAST CODE */ }.
I'm not sure of this but try it.
Depending on the implementation of strategy.process(..) it could be that this implementation has still a reference to the List it passed back as a result. If there are multiple Threads involved in this implementation it might be possible that the List is modified by one of these threads even after it is passed back as a result.
(If you know the "Future" pattern, you could perhaps imagine an implementation where a method immediately returns an empty List and adds the actual results later using another Thread)
You could try to create a new ArrayList "around" the result list and iterate over this copied list.
You might want to read this SO post. Basically switch and use CopyOnWriteArrayList if you can't see where the problem is coming from.
I was going though FIFO implementation in Java and came across this java.util.Queue interface. Dequeue implements it which in turn is implemented by Linked List.
I wrote the following code
public class FIFOTest {
public static void main(String args[]){
Queue<String> myQueue = new LinkedList<String>();
myQueue.add("US");
myQueue.offer("Canada");
for(String element : myQueue){
System.out.println("Element : " + element);
}
}
}
Both seem to do the same thing. Add data to the head of the queue. What is the difference between these two methods? Any special cases in which either would be more beneficial than other?
LinkedList#offer(E) is implemented as
public boolean offer(E e) {
return add(e);
}
In this case, they are the same thing. They are just needed to satisfy the interfaces. LinkedList implements Deque and List. The LinkedList#add(E) method will not throw an Exception as it will always take more elements, but in another Queue implementation that has limited capacity or takes only certain kinds of elements, add(E) might throw an exception while offer(E) will simply return false.
According to the docs the main difference is that when the operation fails, one (add) throws an exception and the other (offer) returns a special value (false):
Each of these methods exists in two forms: one throws an exception if the operation fails, the other returns a special value (either null or false, depending on the operation). The latter form of the insert operation is designed specifically for use with capacity-restricted Queue implementations; in most implementations, insert operations cannot fail.
What is the difference between these two methods?
Queue.add - throws an exception if the operation fails,
Queue.offer- returns a special value (either null or false, depending on the operation).
Any special cases in which either would be more beneficial than other?
According to docs, The Queue.offer form of the insert operation is designed specifically for
use with capacity-restricted Queue implementations; in most
implementations, insert operations cannot fail.
For details, read this docs.
add() comes from Collection Interface.
offer() comes from Queue Interface.
The Documentation of offer() method of Queue says
Inserts the specified element into this queue if it is possible to do
so immediately without violating capacity restrictions.
When using a capacity-restricted queue, this method is generally
preferable to {#link #add}, which can fail to insert an element only
by throwing an exception.
The Documentation of add() method of Queue says
Inserts the specified element into this queue if it is possible to do so
immediately without violating capacity restrictions, returning
<tt>true</tt> upon success and throwing an <tt>IllegalStateException</tt>
if no space is currently available.
Take the PriorityQueue for example http://java.sun.com/j2se/1.5.0/docs/api/java/util/PriorityQueue.html#offer(E)
Can anyone give me an example of a Queue where the add and offer methods are different?
According to the Collection doc, the add method will often seek to ensure that an element exists within the Collection rather than adding duplicates. So my question is, what is the difference between the add and offer methods?
Is it that the offer method will add duplicates regardless? (I doubt that it is because if a Collection should only have distinct elements this would circumvent that).
EDIT:
In a PriorityQueue the add and offer methods are the same method (see my answer below). Can anyone give me an example of a class where the add and offer methods are different?
I guess the difference is in the contract, that when element can not be added to collection the add method throws an exception and offer doesn't.
From: http://java.sun.com/j2se/1.5.0/docs/api/java/util/Collection.html#add%28E%29
If a collection refuses to add a
particular element for any reason
other than that it already contains
the element, it must throw an
exception (rather than returning
false). This preserves the invariant
that a collection always contains the
specified element after this call
returns.
From: http://java.sun.com/j2se/1.5.0/docs/api/java/util/Queue.html#offer%28E%29
Inserts the specified element into
this queue, if possible. When using
queues that may impose insertion
restrictions (for example capacity
bounds), method offer is generally
preferable to method
Collection.add(E), which can fail to
insert an element only by throwing an
exception.
The short answer: it depends on the concrete implementation.
If your queue has a max capacity limit, there actually is a difference.
Case #1 (no max capacity limit) applied:
There is no difference like the implementation of PriorityQueue:
public boolean add(E e) {
return offer(e);
}
Case #2 (max capacity limit) applied:
There actually is a difference like the implementation of ArrayBlockingQueue which extends AbstractQueue :
// ArrayBlockingQueue which extends AbstractQueue
public boolean add(E e) {
return super.add(e);
}
// AbstractQueue
public boolean add(E e) {
if (offer(e))
return true;
else
throw new IllegalStateException("Queue full");
}
offer: if the queue is full, return false and will not throw an exception
add: if the queue is full, throw an exception
The difference is following:
offer method - tries to add an element to a queue, and returns false if the element can't be added (like in case when a queue is full), or true if the element was added, and doesn't throw any specific exception.
add method - tries to add an element to a queue, returns true if the element was added, or throws an IllegalStateException if no space is currently available.
The difference between offer and add is explained by these two excerpts from the javadocs:
From the Collection interface:
If a collection refuses to add a particular element for any reason other than that it already contains the element, it must throw an exception (rather than returning false). This preserves the invariant that a collection always contains the specified element after this call returns.
From the Queue interface
When using queues that may impose insertion restrictions (for example capacity bounds), method offer is generally preferable to method Collection.add(E), which can fail to insert an element only by throwing an exception.
PriorityQueue is a Queue implementation that does not impose any insertion restrictions. Therefore the add and offer methods have the same semantics.
By contrast, ArrayBlockingQueue is an implementation in which offer and add behave differently, depending on how the queue was instantiated.
The Queue interface specifies that add() will throw an IllegalStateException if no space is currently available (and otherwise return true) while offer() will return false if the element couldn't be inserted due to capacity restrictions.
The reason they are the same in a PriorityQueue is that this queue is specified to be unbounded, i.e. there are no capacity restrictions. In the case of no capacity restrictions, the contracts of add() and offer() display the same behaviour.
from the source code in jdk 7 as follow:
public boolean add(E e) {
if (offer(e))
return true;
else
throw new IllegalStateException("Queue full");
}
we can easily know that the add function will return true when successfully add a new element into the queue, but throw a exception when failed .
I will write the java contract example code for the offer method and the add method showing how they differ.
BlockingQueue<String> queue = new ArrayBlockingQueue<>(2);
queue.add("TestQuue1"); // will return true
queue.add("TestQuue2"); // will return true
queue.add("TestQuue3"); // will throw "java.lang.IllegalStateException: Queue full
BlockingQueue<String> queue = new ArrayBlockingQueue<>(2);
queue.offer("TestQuue1"); // will return true
queue.offer("TestQuue2"); // will return true
queue.offer("TestQuue3"); // will return false and will not throw any exception
Source: http://docs.oracle.com/javase/6/docs/api/java/util/Queue.html
The offer method inserts an element if possible, otherwise returning false. This differs from the Collection.add method, which can fail to add an element only by throwing an unchecked exception. The offer method is designed for use when failure is a normal, rather than exceptional occurrence, for example, in fixed-capacity (or "bounded") queues.
offer method throws true or false, if addition is done
add method throws an exception when no addition possible in queue