How to implement a Trie Iterator with Thread run() - java

I have an uni assignment where I need to implement a Trie and it's nodes(Node) and the iterator.
The iterator should iterate over the nodes using a StringBuffer to maintain the status of the word and it should implement the Runnable interface, meaning I have to implement a run() method!
I have tried this implementation:
class NodeIterator implements Iterator<String>, Runnable {
String nextWord;
boolean terminated;
Thread thread;
public NodeIterator() {
thread = new Thread(this,"Node iterator");
thread.start();
}
#Override
public void run() {
terminated = false;
visit(Trie.this.root);
synchronized (this) {
terminated = true;
handshake();
}
}
private void visit(Node node) {
}
private void handshake() {
notify();
try {
wait();
} catch (InterruptedException e) {
}
}
#Override
public boolean hasNext() {
synchronized (this) {
if(!terminated)
handshake();
}
return nextWord != null;
}
#Override
public String next() {
String word = nextWord;
synchronized (this) {
word = null;
}
return word;
}
}
I am missing an implementation for the visit() method as I'm not sure how to "visit" the nodes and I'm not sure the rest is correct as I've never worked with threads.
Should I be doing something differently?
Edit:
public class Trie implements Iterable<String> {
Node root;
...
private static class Node {
private HashMap<Character, Node> children;
private boolean endOfWord;
...
}
}

One way you can implement visit() is with recursion. The recursive method needs to keep track of the prefix of the string built so far, and if it finds a node that ends a word, publishes the string it has found so far. Assuming you can't change the signature for visit(Node), you'll need a helper method:
void visit(Node root) {
visitRecursive("", root);
}
private void visitRecursive(String prefix, Node node) {
if (node.endOfWord) {
nextWord = prefix;
synchronized (this) {
handshake();
}
}
for (Map.Entry<Character, Node> entry : node.children.entrySet()) {
visitRecursive(prefix + entry.getKey(), entry.getValue());
}
}
I'm not sure all your multithreading code is correct, but the very least this will iterate over all strings stored in the trie.

Related

Multithreading with Singleton

I created a PrintQueue class which does printing related job. I made it singleton, as one network printer is shared by many users, so one instance should be created.
Here is my code:
abstract class Document {
protected String name;
protected String type;
Document(){}
Document(String name){
this.name = name;
}
public String name(){
return this.name;
}
abstract public String type();
}
class TextDocument extends Document {
TextDocument(String name){
super(name);
}
#Override
public String type() {
// TODO Auto-generated method stub
return "text";
}
}
class PdfDocument extends Document {
PdfDocument(String name){
super(name);
}
#Override
public String type() {
// TODO Auto-generated method stub
return "PDF";
}
}
class Node {
public Document document;
public Node next;
Node(Document d){
document = d;
}
}
class PrintQueue {
public Node root;
Node cur;
private static PrintQueue instance;
private PrintQueue(){}
public static synchronized PrintQueue getInstance(){
if(instance == null){
instance = new PrintQueue();
}
return instance;
}
public void push(Document d){
if(root == null){
root = new Node(d);
root.next =null;
}else{
cur = root;
while(cur.next!= null){
cur=cur.next;
}
Node newNode = new Node(d);
cur.next = newNode;
newNode.next = null;
}
}
public Document pop(){
if(root == null){
System.out.println("Queue is empty");
return null;
}else{
Node temp = root;
root=root.next;
System.out.println(temp.document.name()+" "+temp.document.type()+" popped out");
return temp.document;
}
}
public void displayContent(){
if(root == null){
System.out.println("no pending task");
}else{
cur = root;
while(cur!=null){
System.out.println(cur.document.name()+" "+cur.document.type());
cur = cur.next;
}
}
}
#Override
public void run() {
// TODO Auto-generated method stub
}
}
public class test {
public static void main(String[] args) {
Document a= new PdfDocument("loan agreement");
Document b= new TextDocument("Air Ticket");
Document c= new PdfDocument("movie ticket");
Document d= new TextDocument("bike riding");
PrintQueue p = PrintQueue.getInstance();
PrintQueue q = PrintQueue.getInstance();
p.push(a);
p.push(b);
q.push(c);
q.push(d);
p.displayContent();
System.out.println("-----------------------------------");
p.pop();
q.pop();
System.out.println("-----------------------------------");
p.displayContent();
}
}
I want to implement multithreading in my code where the push() method should be synchronized. Otherwise, if a document is sent by multiple users to the printer, it will not be saved in the print queue as expected.
I am new to multithreading, so I was thinking that I should extend Thread class to my printQueue, and in the run() method, I will call push(). However, I am unable to send a parameter to push() in that way and as my printQueue is singleton. I can't initialize document to be passed to push() in the constructor of printQueue.
How can I achieve this?
As far as I understand
you are dealing with consumer and producer problem, which is suitable to use BlockingQueue (example updated from doc) to keep the thread safety:
class DocProducer implements Runnable {
private final BlockingQueue queue;
Producer(BlockingQueue q) { queue = q; }
public void run() {
try {
while (true) { queue.put(produce()); }
} catch (InterruptedException ex) { ... handle ...}
}
Document produce() { ... }
}
class DocConsumer implements Runnable {
private final BlockingQueue queue;
Consumer(BlockingQueue q) { queue = q; }
public void run() {
try {
while (true) { consume(queue.take()); }
} catch (InterruptedException ex) { ... handle ...}
}
void consume(Document x) { ... }
}
class Setup {
void main() {
// or use your own thread-safe queue implementation,
// which is harder to be right, though
BlockingQueue printQueue = new LinkedBlockingQueue();
DocProducer p = new DocProducer(printQueue);
DocConsumer c1 = new DocConsumer(printQueue);
DocConsumer c2 = new DocConsumer(printQueue);
new Thread(p).start();
new Thread(c1).start();
new Thread(c2).start();
}
}
use runnalbe rather than extend thread, or better use ExecutorService
you want your consumer and producer to be multithreaded, which should have multi threads, but not your PrintQueue
Your problem is that you want to avoid calling push() method of your PrintQueue by multiple threads at the same time, then just make that method synchronized -
public synchronized void push(Document d){
if(root == null){
root = new Node(d);
root.next =null;
}else{
cur = root;
while(cur.next!= null){
cur=cur.next;
}
Node newNode = new Node(d);
cur.next = newNode;
newNode.next = null;
}
}
By making this method synchronized, you are ensuring that only one thread can enter inside this method at one time so will make this method thread-safe

Duplicated keys in Tree Map when accesing concurrently

Can someone find the concurrency error in this code? The code is working perfectly fine for one thread but as soon I start 2 threads at the same times and I call the addScore method, it is adding duplicates to the tree Map.
The pojo with the comparedTO overrided is as follows:
public final class UserHighScore implements Comparable<UserHighScore>{
private final int userId;
private final int value;
public UserHighScore(int userId, int value) {
this.userId = userId;
this.value = value;
}
public int getUserId() {
return userId;
}
public int getValue() {
return value;
}
#Override
public boolean equals(Object obj) {
if (obj == this) return true;
if (!(obj instanceof UserHighScore)) {
return false;
}
UserHighScore userHighScore = (UserHighScore) obj;
return userHighScore.userId==userId;
}
#Override
public int compareTo(UserHighScore uh) {
if(uh.getUserId()==this.getUserId()) return 0;
if(uh.getValue()>this.getValue()) return 1;
return -1;
}
}
This is the code that I'm using to simulate a User making requests:
class User implements Runnable
{
private ScoreServiceImpl scoreService=ScoreServiceImpl.getInstance();
CountDownLatch latch;
public User(CountDownLatch latch)
{
this.latch = latch;
}
#Override
public void run() {
for(int i=0;i<5;i++) {
scoreService.addScore(3,Integer.parseInt(Thread.currentThread().getName()),ThreadLocalRandom.current().nextInt(50000));
}
System.out.println(scoreService.getHighScoreList(3));
}
}
And the main method to create the threads is:
public static void main(String[] args) throws InterruptedException {
SpringApplication.run(RestclientApplication.class, args);
CountDownLatch latch = new CountDownLatch(1);
User user1=new User(latch);
User user2=new User(latch);
Thread t1=new Thread(user1);
Thread t2=new Thread(user2);
t1.setName("1");
t2.setName("2");
t1.start();
t2.start();
//latch.countDown();
}
Your compareTo is screwy. You can get the same result single threaded with something like this
ScoreServiceImpl.getInstance().addScore(0,1,4);
ScoreServiceImpl.getInstance().addScore(0,1,12);
ScoreServiceImpl.getInstance().addScore(0,0,10);
ScoreServiceImpl.getInstance().addScore(0,0,3);
Tree sets work by divide and conquer, it checks the guy in the middle first. (which will will be 1, 4) and since the userIds don't match it doesn't compare them and compares the values instead. if it had compared the userids it would have gone left but instead it went right and only compared items with a userid of one
You can either always compare on both values or always compare on just userId but you can't switch back and forth.
#Override
public int compareTo(UserHighScore uh) {
return Integer.compare(userId, uh.userId);
}

Asynchronous Iterator

I have the following code:
while(slowIterator.hasNext()) {
performLengthTask(slowIterator.next());
}
Because both iterator and task are slow it makes sense to put those into separate threads. Here is a quick and dirty attempt for an Iterator wrapper:
class AsyncIterator<T> implements Iterator<T> {
private final BlockingQueue<T> queue = new ArrayBlockingQueue<T>(100);
private AsyncIterator(final Iterator<T> delegate) {
new Thread() {
#Override
public void run() {
while(delegate.hasNext()) {
queue.put(delegate.next()); // try/catch removed for brevity
}
}
}.start();
}
#Override
public boolean hasNext() {
return true;
}
#Override
public T next() {
return queue.take(); // try/catch removed for brevity
}
// ... remove() throws UnsupportedOperationException
}
However this implementation lacks support for "hasNext()". It would be ok of course for the hasNext() method to block until it knows whether to return true or not. I could have a peek object in my AsyncIterator and I could change hasNext() to take an object from the queue and have next() return this peek. But this would cause hasNext() to block indefinitely if the delegate iterator's end has been reached.
Instead of utilizing the ArrayBlockingQueue I could of course do thread communication myself:
private static class AsyncIterator<T> implements Iterator<T> {
private final Queue<T> queue = new LinkedList<T>();
private boolean delegateDone = false;
private AsyncIterator(final Iterator<T> delegate) {
new Thread() {
#Override
public void run() {
while (delegate.hasNext()) {
final T next = delegate.next();
synchronized (AsyncIterator.this) {
queue.add(next);
AsyncIterator.this.notify();
}
}
synchronized (AsyncIterator.this) {
delegateDone = true;
AsyncIterator.this.notify();
}
}
}.start();
}
#Override
public boolean hasNext() {
synchronized (this) {
while (queue.size() == 0 && !delegateDone) {
try {
wait();
} catch (InterruptedException e) {
throw new Error(e);
}
}
}
return queue.size() > 0;
}
#Override
public T next() {
return queue.remove();
}
#Override
public void remove() {
throw new UnsupportedOperationException();
}
}
However all the extra synchronizations, waits and notifys don't really make the code any more readable and it is easy to hide a race condition somewhere.
Any better ideas?
Update
Yes I do know about common observer/observable patterns. However the usual implementations don't foresee an end to the flow of data and they are not iterators.
I specifically want an iterator here, because actually the above mentioned loop exists in an external library and it wants an Iterator.
This is a tricky one, but I think I got the right answer this time. (I deleted my first answer.)
The answer is to use a sentinel. I haven't tested this code, and I removed try/catches for clarity:
public class AsyncIterator<T> implements Iterator<T> {
private BlockingQueue<T> queue = new ArrayBlockingQueue<T>(100);
private T sentinel = (T) new Object();
private T next;
private AsyncIterator(final Iterator<T> delegate) {
new Thread() {
#Override
public void run() {
while (delegate.hasNext()) {
queue.put(delegate.next());
}
queue.put(sentinel);
}
}.start();
}
#Override
public boolean hasNext() {
if (next != null) {
return true;
}
next = queue.take(); // blocks if necessary
if (next == sentinel) {
return false;
}
return true;
}
#Override
public T next() {
T tmp = next;
next = null;
return tmp;
}
}
The insight here is that hasNext() needs to block until the next item is ready. It also needs some kind of quit condition, and it can't use an empty queue or a boolean flag for that because of threading issues. A sentinel solves the problem without any locking or synchronization.
Edit: cached "next" so hasNext() can be called more than once.
Or save yourself the headache and use RxJava:
import java.util.Iterator;
import rx.Observable;
import rx.Scheduler;
import rx.observables.BlockingObservable;
import rx.schedulers.Schedulers;
public class RxAsyncIteratorExample {
public static void main(String[] args) throws InterruptedException {
final Iterator<Integer> slowIterator = new SlowIntegerIterator(3, 7300);
// the scheduler you use here will depend on what behaviour you
// want but io is probably what you want
Iterator<Integer> async = asyncIterator(slowIterator, Schedulers.io());
while (async.hasNext()) {
performLengthTask(async.next());
}
}
public static <T> Iterator<T> asyncIterator(
final Iterator<T> slowIterator,
Scheduler scheduler) {
final Observable<T> tObservable = Observable.from(new Iterable<T>() {
#Override
public Iterator<T> iterator() {
return slowIterator;
}
}).subscribeOn(scheduler);
return BlockingObservable.from(tObservable).getIterator();
}
/**
* Uninteresting implementations...
*/
public static void performLengthTask(Integer integer)
throws InterruptedException {
log("Running task for " + integer);
Thread.sleep(10000l);
log("Finished task for " + integer);
}
private static class SlowIntegerIterator implements Iterator<Integer> {
private int count;
private final long delay;
public SlowIntegerIterator(int count, long delay) {
this.count = count;
this.delay = delay;
}
#Override
public boolean hasNext() {
return count > 0;
}
#Override
public Integer next() {
try {
log("Starting long production " + count);
Thread.sleep(delay);
log("Finished long production " + count);
}
catch (InterruptedException e) {
throw new IllegalStateException(e);
}
return count--;
}
#Override
public void remove() {
throw new UnsupportedOperationException();
}
}
private static final long startTime = System.currentTimeMillis();
private static void log(String s) {
double time = ((System.currentTimeMillis() - startTime) / 1000d);
System.out.println(time + ": " + s);
}
}
Gives me:
0.031: Starting long production 3
7.332: Finished long production 3
7.332: Starting long production 2
7.333: Running task for 3
14.633: Finished long production 2
14.633: Starting long production 1
17.333: Finished task for 3
17.333: Running task for 2
21.934: Finished long production 1
27.334: Finished task for 2
27.334: Running task for 1
37.335: Finished task for 1

Why use a "static" class in this way?

I have a FutureContent class which just holds a static reference to a Future class. I'm not sure why it was done this way, it means every method call now does not have to be static. Is there another reason it was done this way ?
//One possible use of Future class
FutureContent.future.deleteContent("test");
public class FutureContent {
public static Future future = new Future();
}
public class Future{
private final Object lock = new Object();
private String str;
private Hashtable content = new Hashtable();
public void addContent(Object key, Object value){
synchronized(lock){
if(content.containsKey(key)){
content.remove(key);
content.put(key, value);
}
else {
content.put(key, value);
}
}
}
public void clearContent(){
content.clear();
}
public void deleteContent(Object key){
if(content.containsKey(key)){
content.remove(key);
}
}
public boolean getBoolean(Object key){
if(!content.contains(key)){
return false;
}
else {
return ((Boolean)content.get(key)).booleanValue();
}
}
public void addBoolean(Object key , boolean value){
Boolean b = new Boolean(value);
synchronized(lock){
if(content.containsKey(key)){
content.remove(key);
content.put(key, b);
}
else {
content.put(key, b);
}
}
}
public Object getContent(Object key){
return content.get(key);
}
public void setString(String str){
synchronized(lock){
this.str = str;
lock.notifyAll();
}
}
public String getString(){
synchronized(lock){
while(this.str == null)
try {
lock.wait();
} catch (InterruptedException e) {
return null;
}
return this.str;
}
}
private JSONObject value;
public void set(JSONObject t){
synchronized(lock){
value = t;
lock.notifyAll();
}
}
public JSONObject get(){
synchronized(lock){
while(value == null)
try {
lock.wait();
} catch (InterruptedException e) {
return null;
}
return value;
}
}
}
It's an approach to provide a pre-allocated object which is typically immutable and can be shared across instances. A common example is Collections.EMPTY_LIST with the signature
public static final List EMPTY_LIST = new EmptyList<Object>();
It is a way to use globals in Java. Although, we cannot directly create global variables in Java, we can achieve almost the same effect with public and static modifiers. Although, there are many disadvantages to globals, it has got some advantages also. We can easily exchange the data from one place, and that will be reflected everywhere. ie., You can store and access common data between different modules and classes, without any hurdles of passing data between them. But beware! -:)

Concurrent Set Queue

Maybe this is a silly question, but I cannot seem to find an obvious answer.
I need a concurrent FIFO queue that contains only unique values. Attempting to add a value that already exists in the queue simply ignores that value. Which, if not for the thread safety would be trivial. Is there a data structure in Java or maybe a code snipit on the interwebs that exhibits this behavior?
If you want better concurrency than full synchronization, there is one way I know of to do it, using a ConcurrentHashMap as the backing map. The following is a sketch only.
public final class ConcurrentHashSet<E> extends ForwardingSet<E>
implements Set<E>, Queue<E> {
private enum Dummy { VALUE }
private final ConcurrentMap<E, Dummy> map;
ConcurrentHashSet(ConcurrentMap<E, Dummy> map) {
super(map.keySet());
this.map = Preconditions.checkNotNull(map);
}
#Override public boolean add(E element) {
return map.put(element, Dummy.VALUE) == null;
}
#Override public boolean addAll(Collection<? extends E> newElements) {
// just the standard implementation
boolean modified = false;
for (E element : newElements) {
modified |= add(element);
}
return modified;
}
#Override public boolean offer(E element) {
return add(element);
}
#Override public E remove() {
E polled = poll();
if (polled == null) {
throw new NoSuchElementException();
}
return polled;
}
#Override public E poll() {
for (E element : this) {
// Not convinced that removing via iterator is viable (check this?)
if (map.remove(element) != null) {
return element;
}
}
return null;
}
#Override public E element() {
return iterator().next();
}
#Override public E peek() {
Iterator<E> iterator = iterator();
return iterator.hasNext() ? iterator.next() : null;
}
}
All is not sunshine with this approach. We have no decent way to select a head element other than using the backing map's entrySet().iterator().next(), the result being that the map gets more and more unbalanced as time goes on. This unbalancing is a problem both due to greater bucket collisions and greater segment contention.
Note: this code uses Guava in a few places.
There's not a built-in collection that does this. There are some concurrent Set implementations that could be used together with a concurrent Queue.
For example, an item is added to the queue only after it was successfully added to the set, and each item removed from the queue is removed from the set. In this case, the contents of the queue, logically, are really whatever is in the set, and the queue is just used to track the order and provide efficient take() and poll() operations found only on a BlockingQueue.
I would use a synchronized LinkedHashSet until there was enough justification to consider alternatives. The primary benefit that a more concurrent solution could offer is lock splitting.
The simplest concurrent approach would be a a ConcurrentHashMap (acting as a set) and a ConcurrentLinkedQueue. The ordering of operations would provide the desired constraint. An offer() would first perform a CHM#putIfAbsent() and if successful insert into the CLQ. A poll() would take from the CLQ and then remove it from the CHM. This means that we consider an entry in our queue if it is in the map and the CLQ provides the ordering. The performance could then be adjusted by increasing the map's concurrencyLevel. If you are tolerant to additional racy-ness, then a cheap CHM#get() could act as a reasonable precondition (but it can suffer by being a slightly stale view).
A java.util.concurrent.ConcurrentLinkedQueue gets you most of the way there.
Wrap the ConcurrentLinkedQueue with your own class that checks for the uniqueness of an add. Your code has to be thread safe.
What do you mean by a concurrent queue with Set semantics? If you mean a truly concurrent structure (as opposed to a thread-safe structure) then I would contend that you are asking for a pony.
What happens for instance if you call put(element) and detect that something is already there which immediately is removed? For instance, what does it mean in your case if offer(element) || queue.contains(element) returns false?
These kinds of things often need to thought about slightly differently in a concurrent world as often nothing is as it seems unless you stop the world (lock it down). Otherwise you are usually looking at something in the past. So, what are you actually trying to do?
Perhaps extend ArrayBlockingQueue. In order to get access to the (package-access) lock, I had to put my sub-class within the same package. Caveat: I haven't tested this.
package java.util.concurrent;
import java.util.Collection;
import java.util.concurrent.locks.ReentrantLock;
public class DeDupingBlockingQueue<E> extends ArrayBlockingQueue<E> {
public DeDupingBlockingQueue(int capacity) {
super(capacity);
}
public DeDupingBlockingQueue(int capacity, boolean fair) {
super(capacity, fair);
}
public DeDupingBlockingQueue(int capacity, boolean fair, Collection<? extends E> c) {
super(capacity, fair, c);
}
#Override
public boolean add(E e) {
final ReentrantLock lock = this.lock;
lock.lock();
try {
if (contains(e)) return false;
return super.add(e);
} finally {
lock.unlock();
}
}
#Override
public boolean offer(E e) {
final ReentrantLock lock = this.lock;
lock.lock();
try {
if (contains(e)) return true;
return super.offer(e);
} finally {
lock.unlock();
}
}
#Override
public void put(E e) throws InterruptedException {
final ReentrantLock lock = this.lock;
lock.lockInterruptibly(); //Should this be lock.lock() instead?
try {
if (contains(e)) return;
super.put(e); //if it blocks, it does so without holding the lock.
} finally {
lock.unlock();
}
}
#Override
public boolean offer(E e, long timeout, TimeUnit unit) throws InterruptedException {
final ReentrantLock lock = this.lock;
lock.lock();
try {
if (contains(e)) return true;
return super.offer(e, timeout, unit); //if it blocks, it does so without holding the lock.
} finally {
lock.unlock();
}
}
}
A simple answer for a queue of unique objects can be as follow:
import java.util.concurrent.ConcurrentLinkedQueue;
public class FinalQueue {
class Bin {
private int a;
private int b;
public Bin(int a, int b) {
this.a = a;
this.b = b;
}
#Override
public int hashCode() {
return a * b;
}
public String toString() {
return a + ":" + b;
}
#Override
public boolean equals(Object obj) {
if (this == obj)
return true;
if (obj == null)
return false;
if (getClass() != obj.getClass())
return false;
Bin other = (Bin) obj;
if ((a != other.a) || (b != other.b))
return false;
return true;
}
}
private ConcurrentLinkedQueue<Bin> queue;
public FinalQueue() {
queue = new ConcurrentLinkedQueue<Bin>();
}
public synchronized void enqueue(Bin ipAddress) {
if (!queue.contains(ipAddress))
queue.add(ipAddress);
}
public Bin dequeue() {
return queue.poll();
}
public String toString() {
return "" + queue;
}
/**
* #param args
*/
public static void main(String[] args) {
FinalQueue queue = new FinalQueue();
Bin a = queue.new Bin(2,6);
queue.enqueue(a);
queue.enqueue(queue.new Bin(13, 3));
queue.enqueue(queue.new Bin(13, 3));
queue.enqueue(queue.new Bin(14, 3));
queue.enqueue(queue.new Bin(13, 9));
queue.enqueue(queue.new Bin(18, 3));
queue.enqueue(queue.new Bin(14, 7));
Bin x= queue.dequeue();
System.out.println(x.a);
System.out.println(queue.toString());
System.out.println("Dequeue..." + queue.dequeue());
System.out.println("Dequeue..." + queue.dequeue());
System.out.println(queue.toString());
}
}

Categories

Resources