ConcurrentLinkedQueue Code Explanation - java

http://www.java2s.com/Open-Source/Java-Open-Source-Library/7-JDK/java/java/util/concurrent/ConcurrentLinkedQueue.java.htm
The above is the source code of ConcurrentLinkedQueue.
I am not able to understand one condition.
How the condition (p == q) will come in the below snippet code from offer method
public boolean offer(E e) {
checkNotNull(e);
final Node<E> newNode = new Node<E>(e);
for (Node<E> t = tail, p = t;;) {
Node<E> q = p.next;
if (q == null) {
// p is last node
if (p.casNext(null, newNode)) {
// Successful CAS is the linearization point
// for e to become an element of this queue,
// and for newNode to become "live".
if (p != t) // hop two nodes at a time
casTail(t, newNode); // Failure is OK.
return true;
}
// Lost CAS race to another thread; re-read next
}
else if (p == q)
// We have fallen off list. If tail is unchanged, it
// will also be off-list, in which case we need to
// jump to head, from which all live nodes are always
// reachable. Else the new tail is a better bet.
p = (t != (t = tail)) ? t : head;
else
// Check for tail updates after two hops.
p = (p != t && t != (t = tail)) ? t : q;
}
}
and also what does the author mean by "We have fallen off List"

The ConcurrentLinkedQueue allows concurrent modification of the internal list while traversing it. This implies that the node you are looking at could have been removed concurrently. To detect such situations the next pointer of a removed node is changed to point to itself. Look at updateHead (L302) for details.

The condition asks the question "Is the current node the same as the next node?"
If so, you've fallen off list ( documentation in line. )
The basic outline of steps is:
create a new node for the offered data.
walk the list to find the last node
insert new node as new tail.
The other parts of the if statement are handling concurrent modification issues.
To better understand what's going on, read Node.casTail() and the casNext()

Related

Java program doesn't terminate. Neither does it shows any output

My Java program regarding Stacks made from LinkedLists. The task at hand was to merge two sorted stacks into one. I think I figured it out but it won't show any output and also it doesn't terminate. Can anyone help?
The "next" instance is pointing to the LinkedList's next element's address in the memory.
void mergeStacks()
{
Stacks sortedMain = new Stacks();
Stacks sorted1 = new Stacks();
Stacks sorted2 = new Stacks();
sorted1.push(1);
sorted1.push(2);
sorted1.push(3);
sorted2.push(4);
sorted2.push(5);
sorted2.push(6);
System.out.println("Stack 1");
sorted1.displayStack();
System.out.println("Stack 2");
sorted2.displayStack();
Node q = sorted1.head,p = sorted2.head,x = sortedMain.head;
while(q.next != null)
{
if(x == null)
{
sortedMain.push(sorted1.pop());
}
while(x.next != null)
{
sortedMain.push(sorted1.pop());
x = x.next;
}
q = q.next;
}
while(p.next != null)
{
while(x.next != null)
{
sortedMain.push(sorted2.pop());
x = x.next;
}
p = q.next;
}
System.out.println("Merged Stack\n");
sortedMain.displayStack();
}
So, I figured out the thing that is causing the console to not show anything. Apparently, the function "pop()" is not really returning int for some reason. Here's the method:
int pop()
{
int popped = 0;
if(isEmpty())
{
System.out.println("Stack is empty");
}
else
{
Node q = head;
while(q.next != null)
{
if(q.next.next == null)
{
popped = q.data;
q.next = null;
top = q;
}
}
}
return popped;
}
Output(With Debugger)
You have this inside the first while loop, which makes no sense:
if(x == null)
{
sortedMain.push(sorted1.pop());
}
while(x.next != null)
{
sortedMain.push(sorted1.pop());
x = x.next;
}
When x is null in the first if statement, how can you then use it in the next while statement? That should produce a null reference exception...
It seems like maybe you think that x would be somehow updated to the new head when you push something into an empty sortedMain? It won't be.
Also, is the "merged" stack supposed to be sorted? Your code appears to be trying to simply push all of the first sorted stack in, followed by pushing all of the second sorted stack in. This may or may not result in an overall sorted stack...depends on the elements within.
What I think should happen is you pop just the first two from each list and do a comparison, pushing whatever is greater/smaller (you didn't specify a sort order). Then you pop the next one from the side that was pushed and repeat. If one side becomes empty, then you'd simply push all the rest from the other side.
From the comments:
I don't really have to define an order in what they are going to
merge. I just want to merge them in whatever order they are into a
third stack. My strategy is to traverse through the first stack and
push all the elements into the main stack and do the same with the
next one.
Did you implement an isEmpty() method for your Stacks class? If so, this is what most people would expect to see:
while(!sorted1.isEmpty())
{
sortedMain.push(sorted1.pop());
}
while(!sorted2.isEmpty())
{
sortedMain.push(sorted2.pop());
}
If you haven't implemented an isEmpty() type method, then you could check to see if the head is null instead? (*I'm assuming you correctly set that to null when the stack is empty!):
while(sorted1.head != null)
{
sortedMain.push(sorted1.pop());
}
while(sorted2.head != null)
{
sortedMain.push(sorted2.pop());
}

How is java.util.concurrent.ConcurrentLinkedQueue#head updated after initialisation?

Environment:
java :java version "1.8.0_201"
os:Ubuntu 16.04.6 LTS Linux version 4.15.0-91-generic
Recently I read the source code of java.util.concurrent.ConcurrentLinkedQueue#offer, and I am confused with the code below.
public boolean offer(E e){
checkNotNull(e);
final Node<E> newNode = new Node<E>(e);
for (Node<E> t = tail, p = t; ; ) {
Node<E> q = p.next;
if (q == null) {
// p is last node
if (p.casNext(null, newNode)) {
......
when ConcurrentLinkedQueue is initialized, the item of head and tail is null.
public ConcurrentLinkedQueue() {
head = tail = new Node<E>(null);
}
but after I first invoke ConcurrentLinkedQueue#offer(with queue.offer(1)) and the code executed the line
p.casNext(null, newNode)(here p and head are the same reference), the reference of head was changed to newNode,and 'item' value of head was change to 1.
Detail of p.casNext is like this
boolean casNext(Node<E> cmp, Node<E> val) {
return UNSAFE.compareAndSwapObject(this, nextOffset, cmp, val);
}
It seems only next filed of head was modified in the cas method, but why was the reference of head changed?
Can you give me some explation? Thanks in advance!
It seems only next field of head was modified, how is the reference of head changed?
Correct, head.next was changed.
The head field of the queue is intentionally not modified by the offer(e) method.
The head and tail fields of the queue are never null, so when the queue is empty, they both refer to the same node, and that node has item = null. It is always valid for one or more nodes to have item = null. Those nodes will be skipped when querying or polling the queue.
It's all done that way to make the code thread-safe without the use of locking.

Implement an algorithm to delete a node in the middle of a single linked list, given only access to that node

Example input: the node ā€˜cā€™ from the linked list a->b->c->d->e Result: nothing is returned, but the new linked list looks like a->b->d->e
I do understand that ppl have already asked this question before, but since my reputation is not high enough yet, I couldn't ask my question in that thread. so here goes my quesetion:
So in the solution, when deleting the middle node we do:
public static boolean deleteNode(LinkedListNode n) {
if (n == null || n.next == null) {
return false; // Failure
}
LinkedListNode next = n.next;
n.data = next.data;
n.next = next.next;
return true;
}
But what I don't understand is that why can't I just do n = next?
It is probably a trivial question, but I didn't seem to find a good explanation for this question
If you just do n = next then you have only changed what object your local reference variable n refers to; you haven't modified any part of the list.
The trick to "deleting" the current node is to overwrite it with the next one:
n.data = next.data;
n.next = next.next;
Now you are modifying fields of the object that is referred to by n, which is a part of the actual list.
In C++, the code you wrote would look like this:
bool deleteNode(LinkedListNode* n) {
if (n == null || (*n).next == null) {
return false; // Failure
}
LinkedListNode* next = (*n).next;
(*n).data = (*next).data;
(*n).next = (*next).next;
return true;
}
So what does that mean? When you call this method, in C++ it would look like this:
LinkedListNode* listNode = new LinkedListNode();
deleteNode(&listNode);
This is important, because that means you're just sending an address over, and not the entire object. This means that you don't actually have access to the node you gave as a parameter to the method, you only have a reference to its address.
Basically, in Java, you can't do the following C++ code:
*n = *next;
You can't modify the listNode object that's outside of the method. You only get its address. And you are only modifying the copy of its address, not the address itself.
Basically, it's because in Java, the pointer of the class is passed by value (as a copy), and primitives are also passed by value (as a copy).
somehow, it overwrites the current node which is supposed to be deleted with the
data of next node to it,and delete the next node.
LinkedListNode next = n.next;
n.data = next.data;
n.next = next.next;
That is how the code comes.

Identify loop or recursion in the list

I want to identify the loop or recursion in the list for the below structure of the node. How can I identify the same?
public class EntityNode {
private EntityNode nextNode; // Points to the next node
}
Example,
Node1 -> Node2 -> Node3 -> Node4 -> Node5 -> Node6 -> Node4
Here, you can see that Node6 is pointing to Node4, and here there comes the looping or recursion and my code will go into infinite. So what if I want to find out this type of scenario with the optimum performance level?
This is actually an interview question I have heard a few times. While I have never tried to implement any sort of loop detection, the answer that most of the interviewers seemed to like is iterating through the list and storing the visited nodes in a hashtable. If you get a collision while storing into the table, then you have a loop in your list.
Edit: In an attempt to offer some code for the example, here is what I would probably try to do (assuming you have some sort of LinkedList<EntityNode> object). I updated this to use a HashSet instead of a HashMap so it was more straightforward (as pointed out by PM 77-1).
public bool detectLoop(LinkedList<EntityNode> list)
{
Set<EntityNode> nodeSet = new HashSet<EntityNode>();
EntityNode curNode = list.getHead();
boolean loopDetected = false;
if(curNode != null)
{
while(curNode.getNextNode() != null && !loopDetected)
{
cureNode = curNode.getNextNode();
loopDetected = !nodeSet.add(curNode);
}
}
return loopDetected;
}
I haven't had the opportunity to test this, but this should work. The reason being that the add() method for a HashSet returns true if this set did not already contain the specified element. So if there is a EntityNode already exists in the set, it will return false, meaning that there was a loop detected.
Since my answer has sort of taken off, I want to say that there are other solutions to this as well. The other one that has been pointed out in this thread is the tortoise and the hare algorithm. You can find more information on that in this thread or at this wiki page.
You should have two EntityNode objects. Both start at Node1. Have the first object move two nodes down, and the second only move one node down. Repeat this until you either reach the end (there was no cycle) or the two objects meet at the same node (there is a cycle).
For your example:
n1: Node1, n2: Node1
n1: Node3, n2: Node2
n1: Node5, n2: Node3
n1: Node4, n2: Node4 -> cycle!!
For pseudocode:
while (n1.nextNode isn't null):
n1 = n1.nextNode.nextNode
n2 = n2.nextnode
if (n1 equals n2): return 'there is a loop!'
I searched on the net and found that this type of problem is called the tortoise and hare algorithm. The Wikipedia page is also here for the same.
As codaddict states in their answer here:
The idea is to have two references to the list and move them at
different speeds. Move one forward by 1 node and the other by 2 nodes.
If the linked list has a loop they will definitely meet.
Else either of the two references(or their next) will become null.
Java code implementing the algorithm:
boolean hasLoop(EntityNode first) {
if (first == null) // list does not exist..so no loop either.
return false;
EntityNode slow, fast; // create two references.
slow = fast = first; // make both refer to the start of the list.
while (true) {
slow = slow.nextNode; // 1 hop.
if (fast.nextNode != null)
fast = fast.nextNode; // 2 hops.
else
return false; // next node null => no loop.
if (slow == null || fast == null) // if either hits null..no loop.
return false;
if (slow == fast) // if the two ever meet...we must have a loop.
return true;
}
}
I think you can make a "visited" flag. Or you can use unintersecting sets, which helps to identify loops in O(N *log N).
P.S. I must admit that this method is more appropriate if you need to build a graph without cycles.
I like Bhavik's answer if you are constrained by memory limits. It doesn't create any possibly large objects to determine the answer.
If there is a loop then the single step and double step methods of walking through the EntityNodes will have to intersect.
Here is sample code to test with -
public class EntityNode {
private EntityNode nextNode = null; // Points to the next node
public static void main(String[] args) {
final EntityNode head = new EntityNode();
// Create small sample (test with even and odd number)
EntityNode tail = head;
for (int i = 0; i < 6; i++) {
EntityNode newNode = new EntityNode();
tail.nextNode = newNode;
tail = newNode;
}
// Add "loop" node
tail.nextNode = head;
System.out.println(detectLoop(head));
}
// Return true if a loop is found
private static boolean detectLoop(EntityNode head) {
boolean loopDetected = false;
if (head != null) {
EntityNode singleStep = head;
EntityNode doubleStep = head;
// If either EntityNode is null and end has been found
while ((singleStep.nextNode != null)
&& (doubleStep.nextNode != null)) {
singleStep = singleStep.nextNode;
// Assert doubleStepper.nextNode != null
doubleStep = doubleStep.nextNode.nextNode;
// If there is a "Collision" then there is a loop
loopDetected = (doubleStep == singleStep);
if (loopDetected) {
break;
}
}
}
return loopDetected;
}
Just traverse the list while keeping every visited node in a hash set. If the node you are adding is ever already present in the set, you have a cycle.
A.-Keep count of the amount of added nodes. Then start a loop through them, while counting the loops. If loopsAmount>nodesAmount, you have recursion.
B.-Keep track of the visited nodes. If a node is visited twice, you have recursion.
C.-Index the nodes while creating them. If node.nextNode.Index-1 != node.Index, you have recursion.

LinkedList remove conditions (last iterated item)

I am attempting to remove the last iterated element, with a custom iterator/linked list class. It for some reason only does this for the first item in the list (the head condition). Is there anything wrong with the conditions?
Should I, instead of the Else after If (prev=head), write If (next != null) to find middle nodes, and If (next = null) to find the last node?
Second question: to remove the items, should I also write prev.element = null (now I only have prev = null, and I suppose that erases the node but not its content.
Quite simply, what is wrong with my remove method, as I cannot figure it out myself. Thank you guys so much in advance. I have been working many hours with this but I still haven't got it working.
public E next() {
if (!hasNext())
throw new NoSuchElementException ();
prev = next;
E element = next.element;
next = next.next;
return element;
}
public void remove() {
if(prev == null) {
throw new IllegalStateException();
}
else {
if(prev == head){
head = head.next;
next = head;
}
else {
next = prev.next;
}
sizeOfList--;
prev = null;
}
}
You would need a while loop to be able to go through every node in the list until you hit the last one. As it is now, your code simply goes past the head, and then gets into the code that says sizeOfList-- and then prev = null;
You need something like this:
while (prev.next.next != null) {
prev = prev.next;
}
prev.next = null;
I do prev.next.next so that you can set the 2nd to last node in your linked list to point to a null value (which is done by prev.next = null;). Think of it this way: prev is the 2nd to last element in the list, prev.next is the last element, and obviously prev.next.next HAS to be null (because prev.next is LAST.) So once this is the case, delete the last element by setting the 2nd to last element to point to a null value.
And then decrement your list count.
This is my best guess with the given code
if(prev == head){ should change to if(prev.equals(head)){ Use equals method.
And I think you have to override equals method in the corresponding element class might definitely help.
== only checks for whether both variables refer to same object in memory, where as equals check Object state.
I hope it helps :).

Categories

Resources