Hi all I have this code:
public class ThreadTester {
public static void main(String args[]) {
Counter c = new Counter();
for (int i = 0; i < 10; i++) {
MyThread a = new MyThread(c);
MyThread b = new MyThread(c);
a.start();
b.start();
}
System.out.println("The value of the balance is " + c.getVal());
}
}
class MyThread extends Thread {
private Counter c;
public MyThread(Counter c){ this.c = c; }
public void run(){ s.increment(); }
}
class Counter {
private int i = 100;
public synchronized void increment(){ i++; }
public synchronized int getVal(){ return i; }
}
Now I thought that this should give the desired result of 120 - however the result seems to fluctuate between 115 and 120. If I add a Thread.sleep(1) after b.start() I always get the desired result of 120. Why does this happen?
It's really been confusing me and I'd appreciate any help I could get, Thanks
You're printing the value of the counter after having started all the threads, and not after all the threads have completed.
Use Thread.join() on all the threads you have started to wait until they've completed, and then print the value. Or use a CountDownLatch. Sleeping gives you the correct result by accident. It allows all the threads to complete, but only because they have so few things to do that sleeping for 1 millisecond is sufficient.
Because threads run in parallel.
You're printing c.getVal() in the main thread before one or more of your other threads has incremented it.
When you sleep, you're allowing the other threads enough time to complete, then printing.
Because not all the threads have completed their increment task by the time you get to the System.out. Injecting the sleep allows the threads to finish before getting to the output.
The reason:
The third Thread (which executes the main()) function gets to the following statement right after starting Threads a and b in random order and that's why you get unpredictable results.
System.out.println("The value of the balance is " + c.getVal());
Next Question:
If I add a Thread.sleep(1) after b.start() I always get the desired result of 120. Why does this happen?
This happens because you stop the main Thread long enough (1 second is a long time in CPU world) to allow Threads a and b to finish.
Solution: Make the main Thread wait until both Threads a and b have finished. One way:
Counter c = new Counter();
for (int i = 0; i < 10; i++) {
MyThread a = new MyThread(c);
MyThread b = new MyThread(c);
a.start();
b.start();
}
a.join(); // wait for thread a to finish
b.join(); // wait for thread b to finish
System.out.println("The value of the balance is " + c.getVal());
You are printing the result potentially before the threads are finished (which is why the results vary). You need to wait until all threads have completed before printing the result.
Restructure your main method as follows:
public static void main(String args[]) {
Counter c = new Counter();
MyThread[] a = MyThread[20];
for (int i = 0; i < 20; i++) {
a[i] = new MyThread(c);
a[i].start();
}
for (int i = 0; i < 20; i++) {
a[i].join();
}
System.out.println("The value of the balance is " + c.getVal());
}
Firstly, I am looping 20 times since your loop iterated 10 times whilst creating two threads (so you were creating 20 threads too). You need to hold on to the references (via the a array) so that the main thread can wait until all the threads have completed (with join). When they have all completed, the correct result is returned.
Related
I work in the multithreading problem where 2 threads are started from the main. The code is provided below,
package com.multi;
public class App {
private int count = 0;
public void doWork() {
Thread thread1 = new Thread(new Runnable() {
public void run() {
for (int i = 0; i < 10000; i++) {
count++;
}
}
});
Thread thread2 = new Thread(new Runnable() {
public void run() {
for (int i = 0; i < 10000; i++) {
count++;
}
}
});
thread1.start();
thread2.start();
try {
thread1.join();
thread2.join();
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("Count is: " + count);
}
public static void main(String[] args) {
App worker = new App();
worker.doWork();
}
}
In the book, it informs that there is a possibility that the count value can be printed less than 20000 in some cases. They provided some explanation but even after reading for few times, I was unable to comprehend that completely. Like there is a try block that join the threads and that meant to ensure to complete both for loops.
a. In which circumstances, the count can be printed less than the 20000 and why both of the threads won't increase the count value?
b. If I wrote like
private volatile int count = 0;
private AtomicInteger count = 0;
will these essentially solve the issue?
Consider this sequence
count is 1
thread1 reads count 1 into local var x
thread2 reads count 1 into local var y
thread1 increments x to 2
thread1 writes x value 2 to count
thread2 increments y to 2
thread2 writes the y value 2 to count
When you do count++, it is a read from the field count, an addition of 1 to the value, and then a write of the result back to the field count, so my example sequence is essentially what can happen in your code.
In my example sequence, even though the field was incremented twice, the count is just 2, and not 3.
This happens because both threads are reading and writing from the same field at the same time.
This is a Java Program to Find The Number with Largest Divisors from 1-500000.
public class Medium2 {
static int count1 = 1;
static int count2 = 1;
static int big_count = 0;
static int big = 0;
Main method
public static void main(String[] args) {
Runnable runnable1 = new Runnable() {
public void run() {
The implementation goes here
for (int num = 1; num <= 500000; num++) {
for (int i = 2; i <= num; i++) {
if (num % i == 0) { //Actual Logic
count1++;
}
}
if (count1 > big_count) {
big_count = count1; //Number of Divisors
big = num; //Largest Number
}
count1 = 1;
}
}
};
And the thread execution
Thread thread1 = new Thread(runnable1); //Threads
Thread thread2 = new Thread(runnable1);
thread1.start();
thread2.start();
try {
thread1.join();
thread2.join();
} catch (InterruptedException ie) {
;
}
System.out.println("Biggest: " + big + "\nNumber of Divisors for " + big + " = " + big_count);
}
}
But it gives different answers every time. The actual answer is : 498960 and 200 Divisors
Concerning your goal, your implementation should probably have problems. Since big_count and big is common for both threads and don't have any protection when threads are trying to modify those, your program should create errors.
Other than that, you are also not utilizing 2 threads, since both threads are doing calculation from 1 to 500000.
Since your calculation logic seems ok, you should get your desired output when you try with single thread.
If you want it to do by two threads, you can easily try this. (just to verify, not the nicest way)
You should have big_count1, big1 and big_count2, big2. So that variables whose names end with '1' is only using by thread1 and variables whose names end with '2' is only using by thread2.
Assign thread1 to check from 1 to 250000 and thread2 to from 250001 to 500000.
After join() s, just compare big_count1 and big_count2, then you can deduce the final answer. :))
I want to know how I can solve the following problem:
I have created multiple threads of the same kind. They are all have a run-method with a timed while-loop and a synchronized-block, in which wait() is called first, then notify(). This results in all threads staying in wait()-state and none of them calling notify().
How can I overcome this deadlock-situation? Is there a solution using wait()/notify()?
public class Deadlock3 implements Runnable {
LinkedList<Integer> intList;
public Deadlock3(LinkedList<Integer> list) {
intList = list;
new Thread(this).start();
}
public void run() {
long startTime = System.currentTimeMillis();
try {
while (System.currentTimeMillis() - startTime < 10) {
synchronized (intList) {
Integer number = intList.removeFirst();
System.out.println(number + " removed");
number = (number + 3) % 21;
intList.addLast(number);
System.out.println(Thread.currentThread().getName()+" - "+number + " added");
intList.wait();
intList.notifyAll();
}
}
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
public static void main(String[] args) {
LinkedList<Integer> list = new LinkedList<Integer>();
for (int i = 0; i < 20; i++) {
list.add(i);
}
for (Integer i : list) {
System.out.println(i);
}
for (int i = 0; i < 4; i++) {
new Deadlock3(list);
}
}
}
Thanks for your answers...
How can I overcome this deadlock-situation? Is there a solution using wait()/notify()?
Let's take a look at your code. You start 4 threads by calling new Thread(this).start(); in the constructor of Deadlock3. That's a really bad pattern by the way because the thread can start using the fields before the object has been fully constructed. It is better to do:
for (int i = 0; i < 4; i++) {
new Thread(new Deadlock3(list)).start();
}
But that's not the problem. When the Deadlock3 starts, the first thread synchronizes on intList, does some counting and stuff, and calls intList.wait(). This waits until someone calls intList.notify() or notifyAll(). The first thread goes to sleep waiting and releases the intList lock. The problem is that each thread goes through the same process. They all are waiting on intList and no one reaches the notifyAll().
The real question is what is the point of calling wait() and notify? As I see it you don't need them and they can be removed. If you need them, please explain why?
When I remove those lines and run the program finishes after spitting out a bunch of the following cycles:
...
18 removed
Thread-3 - 0 added
19 removed
Thread-3 - 1 added
20 removed
Thread-3 - 2 added
0 removed
Thread-3 - 3 added
1 removed
Thread-3 - 4 added
2 removed
...
Hope this helps.
I'm learning threads so I wanted to make a program which has two types of threads: one that writes random numbers and the other one which checks if the current number matches some specific number. The threads call write() and read(int) methods from the Numbers class. To make things more clear, I want my main program to look like this:
Numbers n = new Numbers();
new WritingThread(n);
new ReadingThread(n,3);
new ReadingThread(n,5);
So the output would be something like this:
2
7
3 !!! MATCH !!!
8
5 !!! MATCH !!!
1
...
The thing is that threads are not executed in order. I want to first execute the WritingThread, and then all the ReadingThreads. Because this way a new random number would be written and only one thread would have the chance to check if the numbers match. Here is the code:
class Numbers:
public class Numbers {
int number;
boolean written = false;
public synchronized void write() {
while (written)
try {
wait();
} catch (InterruptedException e1) {
e1.printStackTrace();
}
number = (int) (Math.random() * 10);
System.out.print("\n" + number);
written = true;
notifyAll();
}
public synchronized void check(int n) {
while (!written)
try {
wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.print(" Reading thread: " + Thread.currentThread().getName());
if (n == number)
System.out.print(" !!! MATCH !!! ");
notify();
written = false;
}
}
class WritingThread:
public class WritingThread extends Thread {
Numbers n;
WritingThread(Numbers n){
this.n = n;
start();
}
public void run(){
while(true){
n.write();
}
}
}
class ReadingThread:
public class ReadingThread extends Thread{
Numbers n;
int number;
public ReadingThread(Numbers n, int number){
this.n = n;
this.number = number;
start();
}
public void run(){
while(true){
n.check(number);
}
}
}
And the output:
3 Reading thread: Thread-2
3 Reading thread: Thread-1 !!! MATCH !!!
0 Reading thread: Thread-2
5 Reading thread: Thread-1
0 Reading thread: Thread-2
0 Reading thread: Thread-1
5 Reading thread: Thread-2 !!! MATCH !!!
8 Reading thread: Thread-1
I know i could make one thread which has an array of numbers to check, but I am curious how could it be done this way. Thanks.
Lets start with your example. You have two consumers and one boolean flag. Think through the logic. Let's call our three threads W, C1 and C2.
W post 5
W set flag to true
W send notifyAll
C2 awake
C1 awake
C2 acquire lock
C1 block
C2 no match
C2 notify
W awake
W blocks
C2 release lock
C1 acquire lock
flag is false, C1 waits (releases monitor)
flag is false, C2 waits (releases monitor)
GOTO start
This is just one if the many possible ways in which this code can fun. Any time the lock needs to be acquired there is a free for all and of the threads waiting for it only one can get the lock. That thread will check the value set and reset the flag. If that thread is not the one that the value was intended for it is still consumed.
It should be fairly obvious that you have a race hazard. You are using a single queue for two consumer threads. Each consumer thread is fighting for the queue. Your queue is thread safe in that no more than one thread can read the single item from it at any one time but it causes a race hazard as each consumer thread expects to be the only one reading it. If the wrong thread reads the item then the other thread cannot see it.
The only way to resolve this is to have one queue per thread. The producer puts the same item into each consumer thread's private queue and each consumer thread takes items from its queue and reads them.
Here is an example using an ExecutorSerivce:
public static void main(String[] args) throws Exception {
final class Consumer implements Runnable {
private final BlockingQueue<Integer> q = new LinkedBlockingDeque<>();
private final int search;
public Consumer(final int search) {
this.search = search;
}
#Override
public void run() {
while (true) {
try {
if (q.take() == search) {
System.out.println("Found magic number.");
}
} catch (InterruptedException ex) {
return;
}
}
}
public Queue<Integer> getQ() {
return q;
}
}
final class Producer implements Runnable {
final Random r = new Random();
final Iterable<Queue<Integer>> qs;
public Producer(final Iterable<Queue<Integer>> qs) {
this.qs = qs;
}
#Override
public void run() {
while (true) {
final int i = r.nextInt();
for (final Queue<Integer> q : qs) {
q.offer(i);
}
}
}
}
final int numConsumers = 5;
final Collection<Queue<Integer>> qs = new LinkedList<>();
final ExecutorService es = Executors.newCachedThreadPool();
for (int i = 0; i < numConsumers; ++i) {
final Consumer c = new Consumer(i);
qs.add(c.getQ());
es.submit(c);
}
es.submit(new Producer(qs));
}
You are likely to get very few hits with this example as Random.nextInt() is used. If you want to get more hits reduce the range of the generated random numbers by calling Random.nextInt(int max) which generates numbers [0, max).
As you can see each Consumer has a queue of items to check and it blocks using the BlockingQueue API to wait for new items. The Producer puts the same item into each of the Consumer's queues in turn.
I need a variable to count upwards but in increments of 2 seconds. Right now I'm simply using a ++; function, but as you know it's extremely fast.
Is there anything simple I can use to count at a slower pace?
Thread.sleep(2000);
This will make your program to wait for 2 seconds between this method call and whatever line of execution immediately follows this.
public class Count implements Runnable{
public void run(){
for(int i=0;i<=6;i+=2){
Thread.sleep(2000)//in milliseconds ...sleeping for 2 sec
sysout(...);//print your value
}
}
}
Start it this way
Runnable r=new Count();
Thread t=new Thread(r);
t.start(); // start the thread
What you doing is basicly making a thread and running with a delay.I hope you get a concept
Yes, you can pause the execution for two seconds by using Thread.sleep(2000).
//Your code...
Thread.sleep(2000);
counter = counter + 2;
//Your code...
This will print from 1 to 99, incrementing by 2 with a one second pause between increments.
public static void main(String[] args) {
for (int i = 1; i < 100; i += 2) { // i = i + 2
System.out.printf("i = %d\n", i); // print i = #
try {
Thread.sleep(2000); // two seconds.
} catch (InterruptedException e) {
}
}
}