Not getting expected result when updating AtomicInteger variable in multiple threads - java

In this code I'm using 10 threads updating an AtomicInteger variable. I expect the final result of Counter.getInstance().holder.n to be 1000000, but it prints out random number like 991591.
What's wrong with my code?
public class Test {
public static void main(String[] args) {
List<Thread> list = new ArrayList<Thread>();
for (int i = 0; i < 10; i++) {
list.add(new Thread() {
public void run() {
for (int i = 0; i < 100000; i++) {
Counter.getInstance().holder.n.incrementAndGet();
}
}
});
}
for (Thread thread : list) {
thread.start();
}
try {
Thread.sleep(10000);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println(Counter.getInstance().holder.n);
}
}
class Counter {
private static Counter counter;
Holder holder = new Holder();
public static Counter getInstance() {
if (counter == null) {
counter = new Counter();
}
return counter;
}
class Holder {
AtomicInteger n = new AtomicInteger(0);
}
}

You have two major concurrent issues here:
You don't wait for every Thread to finish work correctly. There are multiple ways to achieve that, the simplest is to use Thread.join().
Your singleton implementation doesn't seem correct. I suppose you intended to implement it with an inner class. It seems that this answer can help to understand what's happening here.
Here is the implementation that seems more or less correct.
class Test {
public static void main(String[] args) throws InterruptedException {
List<Thread> list = new ArrayList<Thread>();
for (int i = 0; i < 10; i++) {
list.add(new Thread() {
public void run() {
for (int i = 0; i < 100000; i++) {
Counter.getInstance().n.incrementAndGet();
}
}
});
}
for (Thread thread : list) {
thread.start();
}
for (Thread thread : list) {
thread.join();
}
System.out.println(Counter.getInstance().n);
}
}
class Counter {
public AtomicInteger n = new AtomicInteger(0);
public static Counter getInstance() {
return Holder.instance;
}
private static class Holder {
private static final Counter instance = new Counter();
}
}
You can use something like CountDownLatch as well. For example:
final int count = 10;
CountDownLatch latch = new CountDownLatch(count);
List<Thread> list = new ArrayList<Thread>();
for (int i = 0; i < count; i++) {
list.add(new Thread() {
public void run() {
for (int i = 0; i < 100000; i++) {
Counter.getInstance().n.incrementAndGet();
}
latch.countDown();
}
});
}
for (Thread thread : list) {
thread.start();
}
latch.await();
System.out.println(Counter.getInstance().n);

Related

Synchronized method in java does not work as indended

I want to learn how to use the synchronized method in java and implemented the following code.
public class checkThread {
volatile int i = 0;
public void increment() {
i++;
}
}
public class TestSync extends checkThread{
public static void main(String[] args) {
checkThread ct1 = new checkThread();
Object iLock = new Object();
for(int i = 0 ; i < 10 ; i++) {
extracted(ct1, iLock);
}
}
private static void extracted(checkThread ct1, Object iLock) {
synchronized (iLock) {
Thread t1 = new Thread(new Runnable() {
#Override
public void run() {
for(int a = 0; a < 1000; a++) {
ct1.increment();
}
}
});
t1.start();
}
synchronized (iLock) {
Thread t2 = new Thread(new Runnable() {
#Override
public void run() {
for(int a = 0; a < 1000; a++) {
ct1.increment();
}
}
});
t2.start();
}
synchronized (iLock) {
System.out.println(ct1.i);
}
}
}
However the output I get is not at all synchronized!
1000
2000
4000
6000
8000
9000
11575
13575
15575
17459
Why am I getting such an output and not the desired value of i in the multiples of 1000?
If you are trying to make sure that the run() method will be completed by one thread before the other one start; then you need to synchronize the content inside the run method, not the thread creation part.
In your specific example, you need to have an object that can be accessed by both the threads, and then acquire the lock of that object.
Let me add an example below by changing your code; but this may not be the best way; just trying to explain the point.
checkThread iLock = new checkThread();
public void someMethod() {
Thread t1 = new Thread(new Runnable() {
#Override
public void run() {
synchronized (iLock) {
for(int a = 0; a < 1000; a++) {
ct1.increment();
}
}
});
t1.start();
}
Thread t2 = new Thread(new Runnable() {
#Override
public void run() {
synchronized (iLock) {
for(int a = 0; a < 1000; a++) {
ct1.increment();
}
}
});
t2.start();
}
synchronized (iLock) {
System.out.println(ct1.i);
}
}

How to share Hashmap between threads in Java?

I am getting empty hashmap when I print it, what's the best approach to Share Static volatile variable between threads?
class RunnableDemo implements Runnable {
int i;
RunnableDemo(int i) {
i = i;
}
public void run(){
finResult.put("value"+str(i), 1);
}
public void start () {
System.out.println("Starting " );
if (t == null) {
t = new Thread (this);
t.start ();
}
}
public class TestThread {
public static volatile ConcurrentHashMap<String, Integer> finResult = new ConcurrentHashMap<String, Integer>();
public static void main(String args[]) {
ThreadPoolExecutor executor = (ThreadPoolExecutor) Executors.newCachedThreadPool();
for(int i=0; i < 4; i++){
RunnableDemo task = new RunnableDemo(i);
executor.execute(task);
}
executor.shutdown();
}
System.out.println(TestThread.finResult);
}
System.out.println(TestThread.finResult); This should print the finResult with all the values from threads.

How to consume in Producer-Consumer using Semphores?

I am trying out the Producer-Consumer problem using Semaphore. The program looks fine to me except for one place.
public class ProducerConsumerWithSemaphores
{
private final ArrayList<Integer> list = new ArrayList<>(5);
private final Semaphore semaphoreProducer = new Semaphore(1);
private final Semaphore semaphoreConsumer = new Semaphore(0);
private void produce() throws InterruptedException
{
for(int i = 0;i< 5;i++)
{
semaphoreProducer.acquire();
list.add(i);
System.out.println("Produced: " + i);
semaphoreConsumer.release();
}
}
private void consumer() throws InterruptedException
{
while (!list.isEmpty()) /// This line is where I have the doubt
{
semaphoreConsumer.acquire();
System.out.println("Consumer: " + list.remove(list.size()-1));
semaphoreProducer.release();
Thread.sleep(100);
}
}
public static void main(String[] args)
{
final ProducerConsumerWithSemaphores obj = new ProducerConsumerWithSemaphores();
new Thread(new Runnable()
{
#Override
public void run()
{
try
{
obj.produce();
} catch (InterruptedException e)
{
e.printStackTrace();
}
}
}).start();
new Thread(new Runnable()
{
#Override
public void run()
{
try
{
obj.consumer();
} catch (InterruptedException e)
{
e.printStackTrace();
}
}
}).start();
}
}
Is it okay to check the list if it is not empty before acquiring the semaphore? Will this cause any problem in multithreaded environment?
private void consumer() throws InterruptedException
{
while (!list.isEmpty()) /// This line is where I have the doubt
The problem is, if consumer runs faster than producer, your consumer quit immediately, then you have no consumer!!
The correct example looks like,
Producer–consumer problem#Using semaphores. I believe your intention is not to use true as endless loop because you want Producer/Consumer to quit when job is done. If that's your intention, you can 1. set a totalCount to end the loop. 2. Or a boolean flag which will be set by producer after putItemIntoBuffer when producer put the last one. The flag must be protected as well as the buffer.(update: this method doesn't work if there's multiple producers/consumers) 3. Simulate EOF ( idea taken from producer - consume; how does the consumer stop?)
Will this cause any problem in multithreaded environment?
Your critical section (your list) is not protected . Usually we use 3 semaphores. The 3rd one is used as a mutex to protect the buffer.
To stop producers/consumers,
Example code with method 1:
public class Test3 {
private Semaphore mutex = new Semaphore(1);
private Semaphore fillCount = new Semaphore(0);
private Semaphore emptyCount = new Semaphore(3);
private final List<Integer> list = new ArrayList<>();
class Producer implements Runnable {
private final int totalTasks;
Producer(int totalTasks) {
this.totalTasks = totalTasks;
}
#Override
public void run() {
try {
for (int i = 0; i < totalTasks; i++) {
emptyCount.acquire();
mutex.acquire();
list.add(i);
System.out.println("Produced: " + i);
mutex.release();
fillCount.release();
}
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
class Consumer implements Runnable {
private final int totalTasks;
Consumer(int totalTasks) {
this.totalTasks = totalTasks;
}
#Override
public void run() {
try {
for (int i = 0; i < totalTasks; i++) {
fillCount.acquire();
mutex.acquire();
int item = list.remove(list.size() - 1);
System.out.println("Consumed: " + item);
mutex.release();
emptyCount.release();
}
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
public void runTest() {
int numProducer = 3;
int tasksPerProducer = 10;
int numConsumer = 6;
int tasksPerConsumer = 5;
for (int i = 0; i < numProducer; i++) {
new Thread(new Producer(tasksPerProducer)).start();
}
for (int i = 0; i < numConsumer; i++) {
new Thread(new Consumer(tasksPerConsumer)).start();
}
}
public static void main(String[] args) throws IOException {
Test3 t = new Test3();
t.runTest();
}
}
Example code with method 3:
public class Test4 {
private Semaphore mutex = new Semaphore(1);
private Semaphore fillCount = new Semaphore(0);
private Semaphore emptyCount = new Semaphore(3);
private Integer EOF = Integer.MAX_VALUE;
private final Queue<Integer> list = new LinkedList<>(); // need to put/get data in FIFO
class Producer implements Runnable {
private final int totalTasks;
Producer(int totalTasks) {
this.totalTasks = totalTasks;
}
#Override
public void run() {
try {
for (int i = 0; i < totalTasks + 1; i++) {
emptyCount.acquire();
mutex.acquire();
if (i == totalTasks) {
list.offer(EOF);
} else {
// add a valid value
list.offer(i);
System.out.println("Produced: " + i);
}
mutex.release();
fillCount.release();
}
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
class Consumer implements Runnable {
#Override
public void run() {
try {
boolean finished = false;
while (!finished) {
fillCount.acquire();
mutex.acquire();
int item = list.poll();
if (EOF.equals(item)) {
// do not consume this item because it means EOF
finished = true;
} else {
// it's a valid value, consume it.
System.out.println("Consumed: " + item);
}
mutex.release();
emptyCount.release();
}
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
public void runTest() {
int numProducer = 3;
int tasksPerProducer = 10;
for (int i = 0; i < numProducer; i++) {
new Thread(new Producer(tasksPerProducer)).start();
}
int numConsumer = numProducer; // producers will put N EOFs to kill N consumers.
for (int i = 0; i < numConsumer; i++) {
new Thread(new Consumer()).start();
}
}
public static void main(String[] args) throws IOException {
Test4 t = new Test4();
t.runTest();
}
}
Instead of using two semaphores why dont you use a single semaphore to such that the synchronization is made between threads link
Additional you can use ArrayBlockingQueue which are thread safe to properly demonstrate the Producer Consumer Problem.

Getting error while implementing Threads

ERROR: local variable t is accessed from within inner class need to be declared final And local variable t1 is accessed from within the class.same with t1.start(); why do I need to declare them final?
public class sync {
public int count = 0;
public static void main(String args[]) {
sync obj = new sync();
obj.dowork();
sync obj1 = new sync();
obj1.dowork1();
System.out.println(count);
}
public void dowork() {
Thread t = new Thread(new Runnable() {
public void run() {
for (int i = 0; i < 1000; i++) {
count++;
}
t.start();
}
});
}
public void dowork1() {
Thread t1 = new Thread(new Runnable() {
public void run() {
for (int i = 0; i < 1000; i++) {
count++;
}
t1.start();
}
});
}
}
I did what you told me really helpful now it's just Showing: System.out.println("count"+count);
Identifier expected plus reach end of file while parsing
t and t1 objects are limited to scope of methods, make them member variables. Secondly, method calls and statements are called from inside a method..here t.start() & t1.start() are just floating loose inside class ... Same goes for print statement it
should also be called from inside a method.
Call to start method should be after the threads (t,t1) has been initialized. Currently they are used inside the initialization process.
It should be like this :
public void dowork(){
Thread t=new Thread (new Runnable (){
public void run(){
for (int i=0;i<1000;i++){
count++;}
}});
t.start();
}
Also count should be a static variable, as you cannot refer non-static variable from inside a static main method.
Your code be like, following think are corrected:
You make count variable static since it is been access with in static main method.
You trying to call Thread.start with in the run method which is wrong, since Thread.start method will call run method.
public class sync {
public static int count = 0;
public static void main(String args[]) {
sync obj = new sync();
obj.dowork();
sync obj1 = new sync();
obj1.dowork1();
System.out.println(count);
}
public void dowork() {
Thread t = new Thread(new Runnable() {
public void run() {
for (int i = 0; i < 1000; i++) {
count++;
}
}
});
t.start();
}
public void dowork1() {
Thread t1 = new Thread(new Runnable() {
public void run() {
for (int i = 0; i < 1000; i++) {
count++;
}
}
});
t1.start();
}
}
public class sync {
static int count = 0;
public static void main(String args[]) {
sync obj = new sync();
obj.dowork();
sync obj1 = new sync();
obj1.dowork1();
System.out.println(count);
}
public void dowork() {
Thread t = new Thread(new Runnable() {
public void run() {
for (int i = 0; i < 1000; i++) {
count++;
}
}
});
t.start();
}
public void dowork1() {
Thread t1 = new Thread(new Runnable() {
public void run() {
for (int i = 0; i < 1000; i++) {
count++;
}
}
});
t1.start();
}
}

How to do something the instant all threads are complete?

Let's say I want to have n threads running and I want to output something when ALL threads complete. Here are the methods I've tried:
//This uses a ThreadGroup called tGroup
while(tGroup.activeCount() > 0) {
try {
Thread.sleep(10000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
This next is just with a while loop and an ArrayList storing Threads
boolean alive = true;
int count = 0;
while (alive) {
count = 0;
for (int i = 0; i < numThreads; i++) {
if (!threads.get(i).isAlive()) {
count++;
}
if (count == numThreads) {
alive = false;
break;
}
}
}
Loop through all your threads and join() each one. The join() will block on any unfinished thread until it finishes.
I think what you want to use is a CountDownLatch as this was built specifically for just this type of situation. Each worker thread will notify the latch when it is complete, and then any threads that have called await() on the latch will hold operation until the count down is complete. Please look at the sample code in the API link I've given above to see how easy and flexible this is to use.
Edit:
Oops, I guess I was too late in posting this. But regardless that you accepted the other answer, you still owe it to yourself to check this out as it is quite elegant and easy to use.
For example:
import java.util.Random;
import java.util.concurrent.CountDownLatch;
public class CountDownLatchEg {
public static void main(String[] args) {
int threadCount = 8;
CountDownLatch latch = new CountDownLatch(threadCount);
System.out.println("Start all threads");
for (int i = 0; i < threadCount; i++) {
new Thread(new MyRunnable(latch, i)).start();
}
System.out.println("All threads started");
try {
latch.await();
} catch (InterruptedException e) {}
System.out.println("All threads finished");
}
}
class MyRunnable implements Runnable {
private CountDownLatch latch;
private Random rand = new Random();
private long delay;
private int id;
public MyRunnable(CountDownLatch latch, int id) {
this.latch = latch;
delay = (rand.nextInt(4) + 1) * 1000;
this.id = id;
}
#Override
public void run() {
System.out.println("Start thread: " + id);
try {
Thread.sleep(delay);
} catch (InterruptedException e) {}
System.out.println("End thread: " + id);
latch.countDown();
}
}
Don't you mean this:
boolean alive = true;
int count = 0;
while (alive) {
count = 0;
for (int i = 0; i < numThreads; i++) {
if (!threads.get(i).isAlive()) {
count++;
}
}
if (count == numThreads) {
alive = false;
}
}
?

Categories