So I have a little problem. I am checking lots of numbers in a loop, where the number is just an AtomicInteger that is incremented every time. The problem is that sometimes there is an "error" (the error has to do with the server, not program) and the thread needs to sleep. After they sleep, I would like all of the threads to go back and recheck the numbers that they missed because of the error, but it will only recheck the last one, because the AtomicInteger was already incremented. Here is my code:
public class Red extends java.lang.Thread {
private final LinkedBlockingQueue<Integer> queue;
public Red(LinkedBlockingQueue<Integer> queue) {
this.queue = queue;
}
public void run()
{
while(true){
try{
int i = queue.take();
Main.code.setValueAttribute(""+i);
HtmlPage reply = (HtmlPage)Main.btnFinal.click();
Main.webClient.waitForBackgroundJavaScript(Main.r.nextInt(500));
if ( reply.asText().indexOf( "Error" ) > -1 || reply.asText().indexOf( "unavailable" ) > -1) {
int sleep = Main.r.nextInt(900000);
System.out.println(" error, on "+i+" sleeping for "+ sleep);
Thread.sleep(sleep);
continue;
}
System.out.println("Code "+i+" checked.");
}catch(Exception e){
e.printStackTrace();
continue;
}
}
}
}
Here is my code for to star the threads:
List<LinkedBlockingQueue<Integer>> queuelist = new ArrayList<LinkedBlockingQueue<Integer>>();
for (int n = 0; n < threads; n++) {
queuelist.add(new LinkedBlockingQueue<Integer>());
java.lang.Thread t = new Red(queuelist.get(n));
t.start();
}
java.lang.Thread a = new MainThread(queuelist);
a.start();
Here is my code for MainThread:
public class MainThread extends java.lang.Thread {
final private List<LinkedBlockingQueue<Integer>> queues;
final private AtomicInteger atomicInteger = new AtomicInteger(10000000);
public MainThread(List<LinkedBlockingQueue<Integer>> queues) {
this.queues = queues;
}
public void run() {
while (true) {
int temp = atomicInteger.getAndIncrement();
for(LinkedBlockingQueue<Integer> queue : queues) {
queue.offer(temp);
}
}
}
}
If I understand the problem, then one solution is to give each thread its own BlockingQueue<Integer> or ConcurrentLinkedQueue<Integer>; the main thread's loop will then increment the AtomicInteger and offer its value to each of the queues, and the threads will take or poll on their queues to retrieve the integers and process them. This way if a thread sleeps it won't miss any integers - they'll be waiting for it in its queue when it wakes up.
public class MainThread extends java.lang.Thread {
final private List<BlockingQueue<Integer>> queues;
final private AtomicInteger atomicInteger = new AtomicInteger();
public MainThread(List<BlockingQueue<Integer>> queues) {
this.queues = queues;
}
public void run() {
while (true) {
int temp = atomicInteger.getAndIncrement();
for(BlockingQueue<Integer> queue : queues) {
queue.offer(temp);
}
}
}
}
public class WorkerThread extends java.lang.Thread {
private final BlockingQueue<Integer> queue;
public WorkerThread(BlockingQueue<Integer> queue) {
this.queue = queue;
}
public void run() {
while(true) {
int temp = queue.take();
// process temp
}
}
}
Related
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);
}
}
}
I have to create a hedge simulator. There is eg. 10 segments of it and each of them should have its own dedicated Thread simulating grow of the segment (each time we're about to calculate whether segment growed up, we should perform random test).
In addition there should be one additional, gardener Thread.
Gardener should cut segment of hence, when its size reaches 10 (then he cuts its size back to initial level of 1 and adds notifies it in his notes).
My attempt to make it working was like this:
public class Segment implements Runnable {
private int currentSize;
#Override
public void run() {
if(Math.random() < 0.3)
incrementSize();
}
private synchronized void incrementSize() {
currentSize++;
}
public synchronized int getCurrentSize() {
return currentSize;
}
public synchronized void setCurrentSize(int newSize) {
currentSize = newSize;
}
}
public class Gardener implements Runnable {
private int[] segmentsCutAmount = new int[10]; //Gardener notes
private Collection<Segment> segments;
public Gardener(Collection<Segment> segmentsToLookAfter) {
segments = segmentsToLookAfter;
}
#Override
public void run() {
while(true) {
//Have no idea how to deal with 10 different segments here
}
}
}
public class Main {
private Collection<Segment> segments = new ArrayList<>():
public void main(String[] args) {
Main program = new Main();
for(int i = 0; i < 10; i++)
program.addSegment();
Thread gardenerThread = new Thread(new Gardener(program.segments));
}
private void addSegment(Collection<Segment> segments) {
Segment segment = new Segment();
Thread segmentThread = new Thread(segment);
segmentThread.start();
segments.add(segment);
}
}
I am not sure what am I supposed to do, when segment reaches max height.
If there was 10 gardeners, every of them could observe one segment, but, unfortunelly, gardener is a lonely shooter - he has no family and his friends are very busy and are not willing to help him. And are you willing to help me? :D
I generally know basics of synchronization - synchronized methods/blocks, Locks, wait and notify methods, but this time I have totally no idea what to do :(
Its like horrible deadlock! Of course I am not expecting to be spoonfeeded. Any kind of hint would be very helpful as well. Thank you in advance and have a wonderful day!
About that queue. You can use the ExecutorService for that.
Letting the Hedge grow
So let's you have a hedge that can grow and be cut.
class Hedge {
private AtomicInteger height = new AtomicInteger(1);
public int grow() {
return height.incrementAndGet();
}
public int cut() {
return height.decrementAndGet();
}
}
And then you have an environment that will let the hedge grow. This will simulate the hedge sections; each environment is responsible for one of the sections only. It will also notify a Consumer<Integer> when the hedge size has gone.
class SectionGrower implements Runnable {
public static final Random RANDOM = new Random();
private final Hedge hedge;
private final Consumer<Integer> hedgeSizeListener;
public SectionGrower (Hedge h, Consumer<Integer> hl) {
hedge = h;
hedgeSizeListener = hl
}
public void run() {
while (true) { // grow forever
try {
// growing the hedge takes up to 20 seconds
Thread.sleep(RANDOM.nextInt(20)*1000);
int sectionHeight = hedge.grow();
hedgeSizeListener.accept(sectionHeight);
} catch (Exception e) {} // do something here
}
}
}
So at this point, you can do this.
ExecutorService growingExecutor = Executors.newFixedThreadPool(10);
Consumer<Integer> printer = i -> System.out.printf("hedge section has grown to %d\n", i.intValue());
for (int i = 0; i < 10; i++) {
Hedge section = new Hedge();
Environment grower = new SectionGrower(section, printer);
growingExecutor.submit(grower::run);
}
This will grow 10 hedge sections and print the current height for each as they grow.
Adding the Gardener
So now you need a Gardener that can cut the hedge.
class Gardener {
public static final Random RANDOM = new Random();
public void cutHedge(Hedge h) {
try {
// cutting the hedge takes up to 10 seconds
Thread.sleep(RANDOM.nextInt(10)*1000);
h.cut();
} catch (Exception e) {} // do something here
}
}
Now you need some construct to give him work; this is where the BlockingQueue comes in. We've already made sure the Environment can notify a Consumer<Integer> after a section has grown, so that's what we can use.
ExecutorService growingExecutor = Executors.newFixedThreadPool(10);
// so this is the queue
ExecutorService gardenerExecutor = Executors.newSingleThreadPool();
Gardener gardener = new Gardener();
for (int i = 0; i < 10; i++) {
Hedge section = new Hedge();
Consumer<Integer> cutSectionIfNeeded = i -> {
if (i > 8) { // size exceeded?
// have the gardener cut the section, ie adding item to queue
gardenerExecutor.submit(() -> gardener.cutHedge(section));
}
};
SectionGrower grower = new SectionGrower(section, cutSectionIfNeeded);
growingExecutor.submit(grower::run);
}
So I haven't actually tried this but it should work with some minor adjustments.
Note that I use the AtomicInteger in the hedge because it might grow and get cut "at the same time", because that happens in different threads.
The in following code Gardner waits for Segment to get to an arbitrary value of 9.
When Segment gets to 9, it notifies Gardner, and waits for Gardner to finish trimming:
import java.util.ArrayList;
import java.util.Collection;
public class Gardening {
public static void main(String[] args) {
Collection<Segment> segments = new ArrayList<>();
for(int i = 0; i < 2; i++) {
addSegment(segments);
}
Thread gardenerThread = new Thread(new Gardener(segments));
gardenerThread.start();
}
private static void addSegment(Collection<Segment> segments) {
Segment segment = new Segment();
Thread segmentThread = new Thread(segment);
segmentThread.start();
segments.add(segment);
}
}
class Gardener implements Runnable {
private Collection<Segment> segments;
private boolean isStop = false; //add stop flag
public Gardener(Collection<Segment> segmentsToLookAfter) {
segments = segmentsToLookAfter;
}
#Override
public void run() {
for (Segment segment : segments) {
follow(segment);
}
}
private void follow(Segment segment) {
new Thread(() -> {
Thread t = new Thread(segment);
t.start();
synchronized (segment) {
while(! isStop) {
try {
segment.wait(); //wait for segment
} catch (InterruptedException ex) { ex.printStackTrace();}
System.out.println("Trimming Segment " + segment.getId()+" size: "
+ segment.getCurrentSize() ); //add size to notes
segment.setCurrentSize(0); //trim size
segment.notify(); //notify so segment continues
}
}
}).start();
}
}
class Segment implements Runnable {
private int currentSize;
private boolean isStop = false; //add stop flag
private static int segmentIdCounter = 0;
private int segmentId = segmentIdCounter++; //add an id to identify thread
#Override
public void run() {
synchronized (this) {
while ( ! isStop ) {
if(Math.random() < 0.0000001) {
incrementSize();
}
if(getCurrentSize() >= 9) {
notify(); //notify so trimming starts
try {
wait(); //wait for gardener to finish
} catch (InterruptedException ex) {
ex.printStackTrace();
}
}
}
}
}
private synchronized void incrementSize() {
currentSize++;
System.out.println("Segment " + getId()+" size: "
+ getCurrentSize() );
}
public synchronized int getCurrentSize() { return currentSize; }
public synchronized void setCurrentSize(int newSize) {
currentSize = newSize;
}
public int getId() { return segmentId; }
}
The mutual waiting mechanizem can be implemented also with CountDownLatch.
Note that my experience with threads is limited. I hope other users comment and suggest improvements.
If I launch for example five threads in main class that will be running parralell
final int TERMINAL_COUNT = 5;
Semaphore semaphore = new Semaphore(1);
Queue<Terminal> terminals = new LinkedList<>();
for (int i = 1; i<= TERMINAL_COUNT; i++){
terminals.offer(new Terminal(i, semaphore));
}
for(Terminal terminal : terminals) terminal.start();
}
And class that carries them looks like
public class Terminal extends Thread {
private Dispetcher dispetcher;
private Semaphore semaphore;
public Terminal(int terminalId, Semaphore semaphore){
dispetcher = new Dispetcher();
this.semaphore = semaphore;
}
#Override
public void run() {
try{
ListIterator<Plane> pIt = dispetcher.getPlanes().listIterator();
while (pIt.hasNext()){
Plane p = pIt.next();
if(!p.isArrived()) {
//some code
replacingPassangers(p);
}
}
}catch (InterruptedException e){
e.printStackTrace();
}
}
private void replacingPassangers(Plane p) throws InterruptedException{
semaphore.acquire();
if(!p.isArrived()) {
//replacing passangers
p.setIsArrived(true);
}
semaphore.release();
}
}
So i need that after passengers is replaced by 1 thread the others skip methods logic with help of if(!p.isArriving) condition. But p.setIsArrived(true); doesn't affects this variable in other threads and as result all threads passing this condition... How can I fix it?
Recently I have delved into the dark arts of Threads, I get how to create them and when to use them and when not to use them. But when I tried to learn how to communicate between them; I Found that Pipes are what you use to do it. I have a Object that is a Instance of one of my Class' that I created, but Pipes seem to be only able to send Byte Arrays or Integers. I wont to be able to use something like a Object Stream to send my object to the other Thread, but my surfing of the internet has gone terribly bad and I am lost. so I Guess the only thing to do is turn to Stack Overflow and see if any one can help. Thank you for the help in advance.
You should use one of the implementations of BlockingQueue.
I most commonly use ArrayBlockingQueue as it allows me to limit the memory footprint of the solution. A LinkedBlockingDeque can be used for an unlimited size but be certain you cannot overload memory.
Here are two threads communicating between themselves using an ArrayBlockingQueue.
public class TwoThreads {
public static void main(String args[]) throws InterruptedException {
System.out.println("TwoThreads:Test");
new TwoThreads().test();
}
// The end of the list.
private static final Integer End = -1;
static class Producer implements Runnable {
final BlockingQueue<Integer> queue;
public Producer(BlockingQueue<Integer> queue) {
this.queue = queue;
}
#Override
public void run() {
try {
for (int i = 0; i < 1000; i++) {
queue.add(i);
Thread.sleep(1);
}
// Finish the queue.
queue.add(End);
} catch (InterruptedException ex) {
// Just exit.
}
}
}
static class Consumer implements Runnable {
final BlockingQueue<Integer> queue;
public Consumer(BlockingQueue<Integer> queue) {
this.queue = queue;
}
#Override
public void run() {
boolean ended = false;
while (!ended) {
try {
Integer i = queue.take();
ended = i == End;
System.out.println(i);
} catch (InterruptedException ex) {
ended = true;
}
}
}
}
public void test() throws InterruptedException {
BlockingQueue<Integer> queue = new LinkedBlockingQueue<>();
Thread pt = new Thread(new Producer(queue));
Thread ct = new Thread(new Consumer(queue));
// Start it all going.
pt.start();
ct.start();
// Wait for it to finish.
pt.join();
ct.join();
}
}
I am trying to understand threads better so i am implementing a simple task:
i have 2 classes that implement runnable. Each one is generating 2 random integers from 1 to 10. ClassA is calculating the sum and ClassB the multiplication. Both are doing this job in a loop for 15 secs.
I have another class called General that has 2 static and synchronized methods: setVal and getVal. Each thread calls General.setVal(result) after each calculation/iteration. setVal only sets the value if it is closer to a number than its previous value. getValue only gets the value.
I have a main class that start each thread. Then there is a loop for 20 secs outputting the value set by the threads. so it is just calling getValue and prints it.
I want each thread, after one iteration to wait and notify the other one to make an iteration and so on... How can i do it?
Here is my code:
public class Particle1 implements Runnable{
//private int x;
private static final int max = 10;
private static final int min = 1;
public void run(){
long t= System.currentTimeMillis();
long end = t+15000;
while(System.currentTimeMillis() < end) {
Random rand = new Random();
int a = rand.nextInt((max - min) + 1) + min;
int b = rand.nextInt((max - min) + 1) + min;
int x = a+b;
System.out.println("P1: "+a+"+"+b+"="+x);
Gather.setRes(x);
//i want it here to sleep until the other one wakes it up.
}
}
}
public class Particle2 implements Runnable{
//private int x;
private static final int max = 10;
private static final int min = 1;
public void run(){
long t= System.currentTimeMillis();
long end = t+15000;
while(System.currentTimeMillis() < end) {
Random rand = new Random();
int a = rand.nextInt((max - min) + 1) + min;
int b = rand.nextInt((max - min) + 1) + min;
int x = a+b;
System.out.println("P2: "+a+"+"+b+"="+x);
Gather.setRes(x);
//i want it here to sleep until the other one wakes it up.
}
}
}
public class Main {
public static void main(String[] args) throws InterruptedException {
Thread thread1 = new Thread(new Particle1());
Thread thread2 = new Thread(new Particle2());
thread1.start();
thread2.start();
long t= System.currentTimeMillis();
long end = t+20000;
while(System.currentTimeMillis() < end) {
System.out.println("Minimum is: "+Gather.getRes());
Thread.sleep(1000);
}
return;
}
}
public class Gather {
public Gather() {
// TODO Auto-generated constructor stub
}
private static int res=1000000;
public static int getRes() {
return res;
}
public synchronized static void setRes(int inres) {
if(Math.abs(inres-250)<res){
res = inres;
}
}
}
Using Threads is normally an exercise for when you want all threads to run independently, not in lock-step with each other.
However, there are times when threads need to communicate amongst themselves - in which case it is common to use some form of BlockingQueue to communicate between them. Here is an example:
public class TwoThreads {
public static void main(String args[]) throws InterruptedException {
System.out.println("TwoThreads:Test");
new TwoThreads().test();
}
// The end of the list.
private static final Integer End = -1;
static class Producer implements Runnable {
final Queue<Integer> queue;
public Producer(Queue<Integer> queue) {
this.queue = queue;
}
#Override
public void run() {
try {
for (int i = 0; i < 1000; i++) {
queue.add(i);
Thread.sleep(1);
}
// Finish the queue.
queue.add(End);
} catch (InterruptedException ex) {
// Just exit.
}
}
}
static class Consumer implements Runnable {
final Queue<Integer> queue;
public Consumer(Queue<Integer> queue) {
this.queue = queue;
}
#Override
public void run() {
boolean ended = false;
while (!ended) {
Integer i = queue.poll();
if (i != null) {
ended = i == End;
System.out.println(i);
}
}
}
}
public void test() throws InterruptedException {
Queue<Integer> queue = new LinkedBlockingQueue<>();
Thread pt = new Thread(new Producer(queue));
Thread ct = new Thread(new Consumer(queue));
// Start it all going.
pt.start();
ct.start();
// Wait for it to finish.
pt.join();
ct.join();
}
}
To truly synchronise between two threads you could use the same mechanism but use a SynchronousQueue instead.