Wait for recursive Thread-Producer - java

I have a gatherer, that searches for moves in a game. I search in a recursive search, to get every possible move from the game.
For performance cause, I use a Threadpool and every found move adds a new Thread to the pool, to maybe extend the old move.
Here is some code:
protected static List<Runnable> threads;
private static ExecutorService threadPool;
protected final synchronized void hookThread(Runnable thread) {
if (threadPool == null) {
threadPool = Executors.newFixedThreadPool(15);
threads = new ArrayList<Runnable>();
}
threadPool.execute(thread);
threads.add(thread);
}
protected abstract class GathererRunnable implements Runnable {
#Override
public final void run() {
onRun();
threads.remove(this);
}
public abstract void onRun();
}
This is a snippet of the parent class. Now comes the child, that searches for the moves.
private void extendMove(final byte[] stones, final ByteLayMove move) {
Runnable r = new GathererRunnable() {
#Override
public void onRun() {
// fancy search stuff
if (moveIsFound)
extendMove(...);
}
};
hookThread(r);
}
The problem is now, that I don't know how I should can wait for the threads to finish.
I tried to use a int, that counts up on Thread Creation and down on Thread Completion, but that also resultet in a too early search abortion.
Do you have an idea if there is a nice way to wait for these threads?
I already thought about a BlockingQueue, but I don't have any idea how to implement it properly.
Greeting Kevin

Below program has implemented producer consumer scenario using BlockingQueue , you can use such approach while writing your own implementation.
import java.util.concurrent.*;
public class ThreadingExample {
public static void main(String args[]){
BlockingQueue<Message> blockingQueue = new ArrayBlockingQueue<Message>(100);
ExecutorService exec = Executors.newCachedThreadPool();
exec.execute(new Producer(blockingQueue));
exec.execute(new Consumer(blockingQueue));
}
}
class Message{
private static int count=0;
int messageId;
Message(){
this.messageId=count++;
System.out.print("message Id"+messageId+" Created ");
}
}
class Producer implements Runnable{
private BlockingQueue<Message> blockingQueue;
Producer(BlockingQueue<Message> blockingQueue){
this.blockingQueue=blockingQueue;
}
#Override
public void run(){
while(!Thread.interrupted()){
System.out.print("Producer Started");
try {
blockingQueue.put(new Message());
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("Producer Done");
}
}
}
class Consumer implements Runnable{
private BlockingQueue<Message> blockingQueue;
Consumer(BlockingQueue<Message> blockingQueue){
this.blockingQueue=blockingQueue;
}
#Override
public void run(){
while(!Thread.interrupted()){
System.out.print("Concumer Started");
try{
Message message = blockingQueue.take();
System.out.print("message Id"+message.messageId+" Consumed ");
}
catch(InterruptedException e){
e.printStackTrace();
}
System.out.println("Concumer Done");
}
}
}

Related

Java Spring Runnable task with timeout

Faced the fact that when the database is unavailable, the queue grows because tasks stop running. What is the best way to set some timeout for tasks executed in method run()? May be there is some good approach with using ExecutorService?
#Service
public class AsyncWriter implements Writer, Runnable {
private LinkedBlockingQueue<Entry> queue = new LinkedBlockingQueue<>();
private volatile boolean terminate = false;
private AtomicInteger completedCounter = new AtomicInteger();
#PostConstruct
private void runAsyncWriter() {
Thread async = new Thread(this);
async.setName("Writer Thread");
async.setPriority(2);
async.start();
}
#Override
public void run() {
while (!terminate) {
try {
Entry entry = queue.take();
dao.save(entry);
completedCounter.incrementAndGet();
}
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
#Override
public void write(Entry entry) {
queue.add(entry);
}
}
Maybe you can try RxJava
https://www.baeldung.com/rx-java
And you can set your aync funtions
Timeout in RxJava

Adding and removing element from list concurrently

I want to create two threads that one adds elements into ArrayList (or vector) and the other removes elements from this list concurrently. For example, if thread1 adds 20 elements into the list, then thread2 starts removing at the same time until total elements are removed, but these two threads must be work at the same time.
I wrote a producer (adding to the list) thread. In this thread, when the number of elements added to the list is greater than 5 or any number, so new thread must be started but in here I am stuck. I will mark the point that I was stuck.
public class Test{
public static void main(String[] args) {
Data d = new Data();
Thread t = new Thread(new producer(d));
t.start();
}
}
class producer implements Runnable{
Data d;
Data d2;
Object lck;
public producer(Data dd)
{
d=dd;
}
#Override
public void run()
{
for (int i=0;i<100;++i ) {
synchronized (d){
d.a.add(i);
// if i is greater than 5,
// start consumer thread
// which remove elements from ArrayList.
// but how ??
Thread t = new Thread(new Runnable(){
#Override
public void run()
{
//if(d.a.isEmpty())
//wait the adder thread
}
});
t.start();
}
}
}
}
class Data{
ArrayList<Integer> a; // or vector
public Data()
{
a = new ArrayList<>();
}
}
How can I implement a remover thread that removes all elements in the list with the same time with adder thread and synchronize them?
You can try concurrent package of java .
https://docs.oracle.com/javase/8/docs/api/java/util/concurrent/CopyOnWriteArrayList.html
You are using synchronized block in thread which will not help in this case. Method in collection or shared data should be synchronized as it will be accessed by multiple thread
In your code, you are creating 100 consumer thread in producer class within synchronized block. This is not efficient way to utilize parallelism using multi-threading. You are creating one thread for one data to be consumed. Once the data is consumed your thread will be in DEAD state and will not be useful to consume other incoming data, this is wastage of resource as well as requires more time to solve problem.
Take reference of below code to solve your consumer producer problem.
import java.util.*;
class Data {
final List<Integer> a;
public Data() {
a = new ArrayList<>();
}
}
public class Producer implements Runnable {
private final Data data;
public Producer(Data data) {
this.data = data;
}
#Override
public void run() {
for (int i = 0; i < 100; i++) {
synchronized (data) {
data.a.add(i);
}
}
}
}
public class Consumer implements Runnable {
private Data data;
private boolean isThreadEnabled = true;
public Consumer(Data data) {
this.data = data;
}
#Override
public void run() {
while (isThreadEnabled) {
synchronized (data) {
if (!data.a.isEmpty()) {
System.out.println(data.a.remove(0));
}
}
}
}
public void stopConsumer() {
isThreadEnabled = false;
}
}
public class ThreadsMain {
public static void main(String args[]) {
try {
Data data = new Data();
Consumer consumerRunnable = new Consumer(data);
Thread producer = new Thread(new Producer(data));
Thread consumer = new Thread(consumerRunnable);
producer.start();
consumer.start();
producer.join();
try {
//wait for consumer to consume data and then stop the thread
Thread.sleep(1000);
consumerRunnable.stopConsumer();
} catch (InterruptedException e) {
e.printStackTrace();
}
} catch (Exception e) {
e.printStackTrace();
}
}
}

asynchronous threads each running an infinite loop

I'm implementing a program which contains different tasks and all have implemented Runnable. e.g. there is a task which works on a database and sends some of the tuples to a synchronized shared memory and subsequently, there is another thread which checks the shared memory and sends messages to a queue. Moreover, these two threads iterate over an infinite while loop.
Already, I have used the fixedThreadPool to execute these threads.
The problem is that sometimes program control remained in the first running thread and the second one never gets the chance to go to its running state.
Here is a similar sample code to mine:
public class A implements Runnable {
#Override
public void run() {
while(true) {
//do something
}
}
}
public class B implements Runnable {
#Override
public void run() {
while(true) {
//do something
}
}
}
public class Driver {
public static void main(String[] args) {
ExecutorService executorService = Executors.newFixedThreadPool(2);
A a = new A();
executorService.execute(a);
B b = new B();
executorService.execute(b);
}
}
I'd also done something tricky, make the first thread to sleep once for a second after a short period of running. As a result, it makes the second thread to find the chance for running. But is there any well-formed solution to this problem? where is the problem in your opinion?
This is a good example of Producer/Consumer pattern. There are many ways of implementing this. Here's one naive implementation using wait/notify pattern.
public class A implements Runnable {
private Queue<Integer> queue;
private int maxSize;
public A(Queue<Integer> queue, int maxSize) {
super();
this.queue = queue;
this.maxSize = maxSize;
}
#Override
public void run() {
while (true) {
synchronized (queue) {
while (queue.size() == maxSize) {
try {
System.out.println("Queue is full, " + "Producer thread waiting for "
+ "consumer to take something from queue");
queue.wait();
} catch (Exception ex) {
ex.printStackTrace();
}
}
Random random = new Random();
int i = random.nextInt();
System.out.println("Producing value : " + i);
queue.add(i);
queue.notifyAll();
}
}
}
}
public class B implements Runnable {
private Queue<Integer> queue;
public B(Queue<Integer> queue) {
super();
this.queue = queue;
}
#Override
public void run() {
while (true) {
synchronized (queue) {
while (queue.isEmpty()) {
System.out.println("Queue is empty," + "Consumer thread is waiting"
+ " for producer thread to put something in queue");
try {
queue.wait();
} catch (Exception ex) {
ex.printStackTrace();
}
}
System.out.println("Consuming value : " + queue.remove());
queue.notifyAll();
}
}
}
}
And here's hot we set things up.
public class ProducerConsumerTest {
public static void main(String[] args) {
Queue<Integer> buffer = new LinkedList<>();
int maxSize = 10;
Thread producer = new Thread(new A(buffer, maxSize));
Thread consumer = new Thread(new B(buffer));
ExecutorService executorService = Executors.newFixedThreadPool(2);
executorService.submit(producer);
executorService.submit(consumer);
}
}
In this case the Queue acts as the shared memory. You may substitute it with any other data structure that suits your needs. The trick here is that you have to coordinate between threads carefully. That's what your implementation above lacks.
I know it may sound radical, but non-framework parts of asynchonous code base should try avoiding while(true) hand-coded loops and instead model it as a (potentially self-rescheduling) callback into an executor
This allows more fair resources utilization and most importantly per-iteration monitoring instrumentation.
When the code is not latency critical (or just while prototyping) the easiest way is to do it with Executors and possibly CompletableFutures.
class Participant implements Runnable {
final Executor context;
#Override
public void run() {
final Item work = workSource.next();
if (workSource.hasNext()) {
context.execute(this::run);
}
}
}

Using Locks and Condition to simulate print server

I want to have print server that outputs the requested messages to the computer screen as follows: Client threads invoke the printRequestV1 method to submit the messages (strings) to be output. But all the printRequestV1 method should do is place the message in the print job queue, and a separate (manager) thread then dequeues messages from the job queue and outputs them to the screen
I know that I need to synchronize the shared request queue and check whether the queue is not empty before trying to remove a message. If the queue is empty, the manager thread needs to wait until client threads add some messages, and the client thread, after adding a message, will let the manager thread know by signaling.
Here what I have so far:
import java.util.*;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;
import java.util.concurrent.locks.Condition;
import static java.lang.System.out;
public class PrintServerV1 implements Runnable {
private static final Queue<String> requests = new LinkedList<String>();
private Lock lock = new ReentrantLock();
private Condition condition = lock.newCondition();
public PrintServerV1() {
try{
while(requests.size() != 0){ condition.await();}
new Thread(this).start();
}
catch (InterruptedException exception) {}
}
public void printRequest(String s) {
lock.lock();
try
{
out.println("Adding print request for: " +s);
requests.add(s);
condition.signalAll();
}
finally { lock.unlock(); }
}
public void sendRequest() throws InterruptedException
{
try {
while(requests.size() != 0){ condition.await();}
out.println("Sending Request to printer");
for(;;) realPrint(requests.remove());
} finally { lock.unlock(); }
}
private void realPrint(String s) {
// do the real work of outputting the string to the screen
out.println("Currently printing: " + s);
}
public void run(){
try{
sendRequest();
} catch (InterruptedException exception) {}
}
public static void main(String[] args){
PrintServerV1 server = new PrintServerV1();
server.printRequest("homework7.txt");
}
}
I am getting the following output:
Adding print request for: homework7.txt
Sending Request to printer
Currently printing: homework7.txt
Exception in thread "Thread-0" java.lang.IllegalMonitorStateException
at java.util.concurrent.locks.ReentrantLock$Sync.tryRelease(ReentrantLock.java:151)
at java.util.concurrent.locks.AbstractQueuedSynchronizer.release(AbstractQueuedSynchronizer.java:1261)
at java.util.concurrent.locks.ReentrantLock.unlock(ReentrantLock.java:457)
at PrintServerV1.sendRequest(PrintServerV1.java:43)
at PrintServerV1.run(PrintServerV1.java:54)
at java.lang.Thread.run(Thread.java:748)
My question is wouldn't it better if make two classes, one named manager who implements runnable and whose sole purpose is to remove from the queue and one class named client who implements runnable and whose purpose is to add requests to the queue?
You can only unlock after you aquire the lock by lock, otherwise IllegalMonitorStateException will be thrown. You should also call await method after you aquiring the lock.
It is a bad idea to await in the construtor, it will cause the creation of instance get blocked;
Remove the elements only when the requests is not empty.
This code works fine on my machine:
import java.util.*;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;
import java.util.concurrent.locks.Condition;
import static java.lang.System.out;
public class PrintServerV1 implements Runnable {
private static final Queue<String> requests = new LinkedList<String>();
private Lock lock = new ReentrantLock();
private Condition condition = lock.newCondition();
public void printRequest(String s) {
lock.lock();
try {
out.println("Adding print request for: " + s);
requests.add(s);
condition.signalAll();
} finally {
lock.unlock();
}
}
public void sendRequest() throws InterruptedException {
lock.lock();
try {
while (requests.size() == 0) {
condition.await();
}
out.println("Sending Request to printer");
while (!requests.isEmpty()) {
realPrint(requests.remove());
}
} finally {
lock.unlock();
}
}
private void realPrint(String s) {
// do the real work of outputting the string to the screen
out.println("Currently printing: " + s);
}
public void run() {
try {
sendRequest();
} catch (InterruptedException exception) {
}
}
public static void main(String[] args) {
PrintServerV1 server = new PrintServerV1();
new Thread(server).start();
server.printRequest("homework7.txt");
}
}
Output:
Adding print request for: homework7.txt
Sending Request to printer
Currently printing: homework7.txt
I suggest to use two threads, one producer and one consumer, as well as a BlockingQueue to solve this kind of problem. The synchronization will be handled by the blocking queue, so you can focus on you business logic.
import java.util.concurrent.LinkedBlockingQueue;
public class Main {
public static void main(String[] args) {
LinkedBlockingQueue<String> queue = new LinkedBlockingQueue<>();
new Thread(new Producer(queue)).start();
new Thread(new Consumer(queue)).start();
}
}
class Consumer implements Runnable {
private LinkedBlockingQueue<String> queue;
public Consumer(LinkedBlockingQueue<String> queue) {
this.queue = queue;
}
#Override
public void run() {
while (true) {
String request;
try {
request = queue.take();
System.out.println(request);
} catch (Exception e) {
}
}
}
}
class Producer implements Runnable {
private LinkedBlockingQueue<String> queue;
public Producer(LinkedBlockingQueue<String> queue) {
this.queue = queue;
}
#Override
public void run() {
try {
queue.put("homework7.txt");
} catch (Exception e) {
}
}
}

How to pause work in particular thread running in ThreadPoolExecutor

In my app I start multiple media downloads in Threads via ThreadPoolExecutor. Now I want to be able to pause particular download threads. How I can do this?
well I'm not sure how you have implemented your code, so I'm just guessing here.
One way of doing this, by keeping track of your Threads,
for example create a Map :
Map<String,Thread> threads=new HashMap<String,Thread>();// ensure each Thread has a unique id, in this case its supposedly a String. then you can control them from outside your thread pool.
here is a hacked implementation:
public class hello{
public static void main(String...strings )throws Exception{
ExecutorService executor = Executors.newFixedThreadPool(5);
Map<String,Thread> threads=new HashMap<String, Thread>();
for(int i=0;i<5;i++){
Thread t = new myRunnable((i+1) +" ");
threads.put((i+1)+"", t);
executor.execute(t);
}
Thread.sleep(2000);
((myRunnable)threads.get("1")).isSuspened=true;
}
private static class myRunnable extends Thread{
String a;
public boolean isSuspened=false;
public myRunnable(String a) {
this.a=a;
// TODO Auto-generated constructor stub
}
#Override
public void run(){
while(true){
if(isSuspened){
continue;
}
try{
System.out.println(a);
Thread.sleep(2000);
}catch(Exception e){}
}
}
}
}

Categories