Count to 10 but thread waits other thread before starting - java

I would like to create a program like this:
I start in my main 10 threads like this (My class implements runnable)
public class Main {
public static void main(String[] ar) {
for (int i = 1; i <= 5; i++) {
Count1by1 count1by1 = new Count1by1(i);
Thread myThread = new Thread(count1by1);
myThread.start();
}
}
}
and I want to create a critical section that if the thread enters it can count to 10, if not it will wait().
I've tried many implementations but is not working (cuz every threads count to 10 without waiting...
This is the class
public class Count1by1 implements Runnable{
private int threadnumber;
private Object mutex = new Object();
public Count1by1(int num) {
this.threadnumber=num;
//this.mutex= new Object();
}
public void count() {
synchronized (mutex) {
for (int i = 1; i <= 10; i++) {
System.out.println("#"+threadnumber + " counts: " + i);
try {
Thread.sleep(500);
} catch (Exception e) {
System.out.println(e);
}
}
}
}
#Override
public void run() {
count();
}
}

private Object mutex = new Object();
Okay. You create a new object. It has no name (because objects do not have names). You also created a field (which isn't an object; it's a pointer to one). It currently points at the new object you made.
Each of the 10 instances of Count1by1 has a field, and each points to a unique object, given that they all run new Object().
synchronized (mutex) {
Okay, this takes the field mutex follows what its pointing at, finds the object there, and then locks on that. Given that there are 10 unique objects (each Count1by1 instance has its own object), this accomplishes nothing. To have a mutex, at least 2 threads need to lock on the same object.
Solution
Make the lock object in your main and pass it to your threads:
private final Object mutex;
public Count1by1(int num, Object mutex) {
this.threadnumber=num;
this.mutex = mutex;
}
Now there's one mutex object (hint: Count the number of times the code executes a new statement, that's how many you have). Each of your 10 instances of Count1by1 has its own field, but they are all pointing at the same object (it's like 10 people having a piece of paper with the same home address written on it: 10 'variables', just one house), hence, synchronizing on them will do something.

Related

My concurrent code is synchronised but it is not printing values in sync however each thread prints the same value

I am trying to demonstrate how to fix a RaceCondition using the synchronized keyword. The below code consists of a ZooStock objects' variable being incremented and printed by 4 threads. I have synchronized the method (addGrass()) however the values being printed by all threads are the same i.e.
Current output: 1002g, 1002g, 1002g, 1002g
Expected output: 1001g, 1002g, 1003g, 1004g
public static void main(String[] args){
ZooStockSync zooStockNew = new ZooStockSync(1000, 750, 5000);
ExecutorService executorService = null;
try{
executorService = Executors.newFixedThreadPool(10); //Creating a Thread pool of size 10
for(int i=0; i<4; i++){
executorService.submit(()->new ZooWorkerSync(zooStockNew).addGrass()); //
}
}finally{
if(executorService != null) executorService.shutdown();
}
}
Class containing synchronized method:
class ZooWorkerSync implements Runnable {
ZooStockSync zooStock;
ZooWorkerSync(ZooStockSync zooStock){
this.zooStock = zooStock;
}
public synchronized void addGrass(){
zooStock.grass++;
System.out.print(zooStock.grass + "g ");
}
}
However when I create Threads in a traditional (java.lang.Thread) sense without using the Executor threads from java.util.concurrent package.
public static void main(String[] args){
ZooStockSync zooStockTraditional = new ZooStockSync(1000, 750, 5000);
ZooWorkerSync[] workerThreads = new ZooWorkerSync[4]; //Set all elements in the array to be a ZooWorker object
Arrays.fill(workerThreads, new ZooWorkerSync(zooStockTraditional));
for (ZooWorkerSync workerThread : workerThreads) {
new Thread(workerThread).start(); //Start the worker threads off (this invokes the run method in the ZooWorker class)
}
}
The output is as expected: 1001g 5010w 751h 1002g 5020w 752h 1003g 5030w 753h 1004g 5040w 754h, notice the g's are in ascending order as expected. (Ignore the h's and w's)
The worker thread's run method is shown below:
#Override
public void run() {
addGrass();
addWater();
addHay();
}
So my question is, why do the 2 outputs differ, why am I getting the same value printed using the java.util.concurent Executors' threads opposed to the traditional method?
In your ExeutorService example, you're creating multiple instances of the ZooWorkerSync class, in the Thread example you're reusing the same instance.
In your first example, the synchronized keyword doesn't really do anything since it's an instance level lock. You could try manually synchronizing on the class instead.
synchronized locks an object, and because you are sync'ing on multiple object, it isn't working as you'd like.
Instead, you should synchronize on a common object, like the class.
class ZooWorkerSync implements Runnable {
ZooStockSync zooStock;
ZooWorkerSync(ZooStockSync zooStock){
this.zooStock = zooStock;
}
public void addGrass(){
synchronized (ZooWorkerSync.class) {
zooStock.grass++;
System.out.print(zooStock.grass + "g ");
}
}
}
I don't see the code for ZooStockSync but it looks like you're synchronizing a method on the thread (ZooWorkerSync) and not the object being shared. You then access a field in ZooStockSync:
public synchronized void addGrass(){
zooStock.grass++;
System.out.print(zooStock.grass + "g ");
}
But access to that field (grass) may not be thread safe. Each ZooWorkerSync thread can access that field simultaneously. I would suggest putting synchronized on a method in ZooStockSync that increments the field. For example:
public synchronized void incrementGrass() {
grass++;
}
You can also use the volatile keyword for the grass field, or make it an AtomicInteger.
The error arises from me creating several instances of ZooWorkerSync in the Executors example, the use of the word synchronized as demonstrated above works as an instance level lock, so it is practically redundant across multiple instances, it will only be useful for a single instance, hence I need to modify my executorService to only invoke addGrass() from a single instance:
public static void main(String[] args){
ZooStockSync zooStockNew = new ZooStockSync(1000, 750, 5000);
ExecutorService executorService = null;
try{
executorService = Executors.newFixedThreadPool(10); //Creating a Thread pool of size 10
ZooWorkerSync zooWorkerSync = new ZooWorkerSync(zooStockNew);
for(int i=0; i<4; i++){
executorService.submit(zooWorkerSync::addGrass);
}
}finally{
if(executorService != null) executorService.shutdown();
}
}

Threads with shared integer object not working as expected

I have a problem where i have to print the numbers in such format.
First 1
First 2
Second 3
Second 4
First 5
First 6
Second 7
Second 8
First 9
and so on...
I have implemented my runnable interface as below.
class ThreadDemo implements Runnable {
public volatile Integer num;
public Object lock;
public ThreadDemo(Integer num, Object lock) {
this.num = num;
this.lock = lock;
}
#Override
public void run() {
try {
while (true) {
int count = 0;
synchronized(lock) {
Thread.sleep(100);
while (count < 2) {
System.out.println(Thread.currentThread().getName() + " " + num++);
count++;
}
lock.notify();
lock.wait();
}
}
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
My main class is as follows
public class CoWorkingThreads {
private static volatile Integer num = new Integer(1);
public static void main(String...args) {
Object lock = new Object();
Thread thread1 = new Thread(new ThreadDemo(num, lock), "First");
thread1.start();
Thread thread2 = new Thread(new ThreadDemo(num, lock), "Second");
thread2.start();
}
}
when i run the program i am getting the output as follows
First 1
First 2
Second 1
Second 2
First 3
First 4
Second 3
Second 4
Instead of previously expected results. But when I Change the integer to atomic integer type i start getting the expected result. can anyone explain what is i can do to make it run with integer instead of using atomic integer
Java Integer cannot be passed by reference. On your code, each thread will create a copy of the variable. However atomicInteger can be passed by reference.
Also, to get the correct result, you can change the num variable to static variable.
public static Integer num = 1;
public Object lock;
public ThreadDemo(Integer num, Object lock) {
//this.num = num;
this.lock =lock;
}
Your problem is that the Integer class is Immutable, so you cannot use it in separate threads to reference a shared value. Answer: Create your own, Mutable, Integer class.
You can find a similar question answered on SO here
Just for your knowledge, instead of using a synchronized block, on an Object, you might want to experiment with Lock(s) (e.g. ReentrantLock) and their associated Condition(s).
Using Condition(s) you can manage your shared resources in a mutually exclusive way between threads.
I still believe that this question is NOT answered correctly. The flaw here is that you have never marked shared data as static. So each thread has it's own copy independent of the other. Integer is an immutable wrapper class, which is true but it has nothing to do in this context. Let's dig more into num++. The ++ operator applies only to (primitive) integer types. Behind the scenes, num is unboxed, the ++ is applied, and the result is then assigned back to num (after a boxing conversion). The Integer class does not have a ++ operator. In fact, Integer objects are immutable.
Immutable means every time you increment and create a new value object. And that new value object is assigned back to your num reference. But two threads have their own copy of num reference pointing to different Integer boxed primitives. So they increment it independently of one another which is not visible to the other. If you want to share it between threads you have to use static access modifier at the site of declaration. More over a passing two values to a shared variable does not make sense. Instead you can initialize it inline. Here's the fixed version.
public class ThreadDemo implements Runnable {
public static Integer num = 1;
public static final Object lock = new Object();
public ThreadDemo() {
}
#Override
public void run() {
try {
while (true) {
int count = 0;
synchronized (lock) {
Thread.sleep(100);
while (count < 2) {
System.out.println(Thread.currentThread().getName() + " " + num++);
count++;
}
lock.notify();
lock.wait();
}
}
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
public class CoWorkingThreads {
public static void main(String[] args) {
Thread thread1 = new Thread(new ThreadDemo(), "First");
thread1.start();
Thread thread2 = new Thread(new ThreadDemo(), "Second");
thread2.start();
}
}
Finally use of a client provided lock object violates the encapsulation of synchronization policy. So I have used an internal private lock object instead.
Here's the new output.
First 1 First 2 Second 3 Second 4 First 5 First 6 Second 7
Second 8 First 9 First 10

Synchronise ArrayList over two threads

I'm having a difficult time understanding how to synchronise an ArrayList over two threads. Basically, I want one thread appending objects to the list and the other one reading from that list at the same time.
Here is the class that deploys the threads:
public class Main {
public static ArrayList<Good> goodList = new ArrayList();
public static void main(String[] args) {
Thread thread1 = new Thread(new GoodCreator());
Thread thread2 = new Thread(new WeightCounter());
thread1.start();
thread2.start();
}
}
Then the two Runnable classes:
This one reads lines of two values from a text file and appends new objects.
public class GoodCreator implements Runnable{
private ArrayList<Good> goodList = Main.goodList;
private static Scanner scan;
#Override
public void run() {
System.out.println("Thread 1 started");
int objCount = 0;
try {
scan = new Scanner(new File(System.getProperty("user.home") + "//Goods.txt"));
} catch (FileNotFoundException e) {
System.out.println("File not found!");
e.printStackTrace();
}
while(scan.hasNextLine()){
String line = scan.nextLine();
String[] words = line.split("\\s+");
synchronized(goodList){
goodList.add(new Good(Integer.parseInt(words[0]), Integer.parseInt(words[1])));
objCount++;
}
if(objCount % 200 == 0) System.out.println("created " + objCount + " objects");
}
}
}
This iterates over the arraylist and is supposed to sum up one of the fields.
public class WeightCounter implements Runnable{
private ArrayList<Good> goodList = Main.goodList;
#Override
public void run() {
System.out.println("Thread 2 started");
int weightSum = 0;
synchronized(goodList){
for(Good g : goodList){
weightSum += g.getWeight();
}
}
System.out.println(weightSum);
}
}
No matter the input, weightSum never gets incremented and stays 0
Thread 1 started
Thread 2 started
0
Any help is much appreciated
You are running two independently running threads. These thread can run in any order and if one stop e.g. to read from a file, the other thread doesn't assume it has to wait for it.
In short, your second thread completes before the first thread has added anything to the list.
There is no good fix as this is not a good example of why you would use multiple threads, however to get an outcome what you can do is this.
public class WeightCounter implements Runnable{
private ArrayList<Good> goodList = Main.goodList;
#Override
public void run() {
System.out.println("Thread 2 started");
for(int i = 0; i < 10; i++) {
try {
Thread.sleep(100);
} catch (InterruptedException ie) {
throw AssertionError(ie);
}
int weightSum = 0;
synchronized(goodList){
for (Good g : goodList)
weightSum += g.getWeight();
}
System.out.println(weightSum);
}
}
}
This will print the sum 10 times, 0.1 seconds apart. Depending on how long your file takes to load you will be able to see the sum for what has loaded so far.
This is something called a producer-consumer task. You can do it with arraylist, but it's honestly just not the right way to approach this problem.
Luckily, Java provides us with some collections, the BlockingQueue collections, which are designed specifically for this reason;
//the collection with the stuff in it
static BlockingQueue<Object> items = new BlockingQueue<Object>();
//(there are a few different types of blocking queues, check javadocs.
//you would want Linked or Array blocking queue
//what happens on the reader thread
public void producer()
{
//read the data into the collection
for (all the data in the file)
{
//add the next item
items.put(/* next item from file or w/e */);
//stop if necessary
if (atEndOfFile) stillReadingData = false;
//etc
}
}
Now you need to read the data out of the queue - luckily this is easy enough;
//what happens on the other threads
public void consumer()
{
//keep this thread alive so long as there is data to process
//or so long as there might be more data to process
while (stillReadingData || !items.isEmpty())
{
//get the next item from the list
//while the list is empty, we basically sleep for "timeout" timeunits,
//then the while-loop would repeat, and so on
Object o = items.poll(long timeout, int units);
if (o != null) //process it
}
}
In this way, you can continuously add items to the queue with the producer thread, and the items will be processed as soon as a consumer thread is free (this approach scales well with lots of consumer threads). If you still need a collection for the items, then you should make a second collection and add them to that after they have been processed.
As a side note, you may still need to synchronize oprations which occur while processing the items. For example, you would need to synchronize increments on "weightSum" (or alternately use AtomicInteger).
Try this change in the WeightCounter class.
public class WeightCounter implements Runnable{
private ArrayList<Good> goodList = Main.goodList;
#Override
public void run() {
System.out.println("Thread 2 started");
int weightSum = 0;
while(goodList.isEmpty()) {
Thread.sleep(1000);
}
synchronized(goodList){
for(Good g : goodList){
weightSum += g.getWeight();
}
}
System.out.println(weightSum);
}
}
This change will cause the WeightCounter thread to wait for the other thread to finish populating the goodList with data before attempting to read from it.

Multi-threading program to print numbers from 1 to 50?

im trying to write a program in which two threads are created and the output should be like 1st thread prints 1 and the next thread prints 2 ,1st thread again prints 3 and so on. im a beginner so pls help me clearly. i thought thread share the same memory so they will share the i variable and print accordingly. but in output i get like thread1: 1, thread2 : 1, thread1: 2, thread2 : 2 nd so on. pls help. here is my code
class me extends Thread
{
public int name,i;
public void run()
{
for(i=1;i<=50;i++)
{
System.out.println("Thread" + name + " : " + i);
try
{
sleep(1000);
}
catch(Exception e)
{
System.out.println("some problem");
}
}
}
}
public class he
{
public static void main(String[] args)
{
me a=new me();
me b=new me();
a.name=1;
b.name=2;
a.start();
b.start();
}
}
First off you should read this http://www.oracle.com/technetwork/java/codeconventions-135099.html.
Secondly the class member variables are not shared memory. You need to explicitly pass an object (such as the counter) to both objects, such that it becomes shared. However, this will still not be enough. The shared memory can be cached by the threads so you will have race-conditions. To solve this you will need to use a Lock or use an AtomicInteger
It seems what you want to do is:
Write all numbers from 1 to 50 to System.out
without any number being printed multiple times
with the numbers being printed in order
Have this execution be done by two concurrent threads
First, let's look at what is happening in your code: Each number is printed twice. The reason for this is that i is an instance variable of me, your Thread. So each Thread has its own i, i.e., they do not share the value.
To make the two threads share the same value, we need to pass the same value when constructing me. Now, doing so with the primitive int won't help us much, because by passing an int we are not passing a reference, hence the two threads will still work on independent memory locations.
Let us define a new class, Value which holds the integer for us: (Edit: The same could also be achieved by passing an array int[], which also holds the reference to the memory location of its content)
class Value{
int i = 1;
}
Now, main can instantiate one object of type Value and pass the reference to it to both threads. This way, they can access the same memory location.
class Me extends Thread {
final Value v;
public Me(Value v){
this.v = v;
}
public void run(){
for(; v.i < 50; v.i++){
// ...
}
public static void main(){
Value valueInstance = new Value();
Me a = new Me(valueInstance);
Me b = new Me(valueInstance);
}
}
Now i isn't printed twice each time. However, you'll notice that the behavior is still not as desired. This is because the operations are interleaved: a may read i, let's say, the value is 5. Next, b increments the value of i, and stores the new value. i is now 6. However, a did still read the old value, 5, and will print 5 again, even though b just printed 5.
To solve this, we must lock the instance v, i.e., the object of type Value. Java provides the keyword synchronized, which will hold a lock during the execution of all code inside the synchronized block. However, if you simply put synchronize in your method, you still won't get what you desire. Assuming you write:
public void run(){ synchronized(v) {
for(; v.i < 50; v.i++) {
// ...
}}
Your first thread will acquire the lock, but never release it until the entire loop has been executed (which is when i has the value 50). Hence, you must release the lock somehow when it is safe to do so. Well... the only code in your run method that does not depend on i (and hence does not need to be locking) is sleep, which luckily also is where the thread spends the most time in.
Since everything is in the loop body, a simple synchronized block won't do. We can use Semaphore to acquire a lock. So, we create a Semaphore instance in the main method, and, similar to v, pass it to both threads. We can then acquire and release the lock on the Semaphore to let both threads have the chance to get the resource, while guaranteeing safety.
Here's the code that will do the trick:
public class Me extends Thread {
public int name;
final Value v;
final Semaphore lock;
public Me(Value v, Semaphore lock) {
this.v = v;
this.lock = lock;
}
public void run() {
try {
lock.acquire();
while (v.i <= 50) {
System.out.println("Thread" + name + " : " + v.i);
v.i++;
lock.release();
sleep(100);
lock.acquire();
}
lock.release();
} catch (Exception e) {
System.out.println("some problem");
}
}
public static void main(String[] args) {
Value v = new Value();
Semaphore lock = new Semaphore(1);
Me a = new Me(v, lock);
Me b = new Me(v, lock);
a.name = 1;
b.name = 2;
a.start();
b.start();
}
static class Value {
int i = 1;
}
}
Note: Since we are acquiring the lock at the end of the loop, we must also release it after the loop, or the resource will never be freed. Also, I changed the for-loop to a while loop, because we need to update i before releasing the lock for the first time, or the other thread can again read the same value.
Check the below link for the solution. Using multiple threads we can print the numbers in ascending order
http://cooltekhie.blogspot.in/2017/06/#987628206008590221

Multiple Threads accessing instance method from different Instances should cause a race condition?

I am trying to understand Synchornized in Java.
I understood if I have access a synchronized method on same object from 2 different Threads, only one will be able to access at a time.
But I think if the same method is being called on 2 different instances, Both Objects should be able to access the method parallel. Which would cause race condition if accessing/modifying a static member variable from the method. But I am not able to see the race condition happening in below code.
Could someone please explain whats wrong with the code or my understanding.
For reference code is accessible at : http://ideone.com/wo6h4R
class MyClass
{
public static int count=0;
public int getCount()
{
System.out.println("Inside getcount()");
return count;
}
public synchronized void incrementCount()
{
count=count+1;
}
}
class Ideone
{
public static void main(String[] args) throws InterruptedException {
final MyClass test1 = new MyClass();
final MyClass test2 = new MyClass();
Thread t1 = new Thread() {
public void run()
{
int k=0;
while (k++<50000000)
{
test1.incrementCount();
}
}
};
Thread t2 = new Thread() {
public void run()
{
int l=0;
while (l++<50000000)
{
test2.incrementCount();
}
}
};
t1.start();
t2.start();
t1.join();
t2.join();
//System.out.println(t2.getState());
int x=500000000+500000000;
System.out.println(x);
System.out.println("count = " + MyClass.count);
}
}
You're right that the race condition exists. But the racy operations are so quick that they're unlikely to happen -- and the synchronized keywords are likely providing synchronization "help" that, while not required by the JLS, hide the races.
If you want to make it a bit more obvious, you can "spell out" the count = count + 1 code and put in a sleep:
public synchronized void incrementCount()
{
int tmp = count + 1;
try {
Thread.sleep(500);
} catch (InterruptedException e) {
e.printStackTrace();
}
count=tmp;
}
That should show the races more easily. (My handling of the interrupted exception is not good for production code, btw; but it's good enough for small test apps like this.)
The lesson learned here is: race conditions can be really hard to catch through testing, so it's best to really understand the code and prove to yourself that it's right.
Since syncrhonized methods actually synchronize on this different instance methods will lock on different objects and therefore you will get race conditions since they don't block each other.
You probably have to make your own lock object and lock on that.
class MyClass
{
public static int count=0;
//this is what you lock on
private static Object lock = new Object();
public int getCount()
{
synchronized(lock){
System.out.println("Inside getcount()");
return count;
}
}
public void incrementCount()
{
synchronized(lock){
count = count+1;
}
}
//etc
Now when you run your main, this gets printed out:
1000000000
count = 100000000
Here's the relevant section of the Java specification:
"A synchronized method acquires a monitor (ยง17.1) before it executes. For a class (static) method, the monitor associated with the Class object for the method's class is used. For an instance method, the monitor associated with this (the object for which the method was invoked) is used."
However I fail to see where the MyClass' instances are actually incrementing "count" so what exactly are you expecting to show as a race condition?
(Taken originally from this answer)

Categories

Resources