3

The counter variable does not accurately reflect how many times increment method is invoked. Why not, and how can it be fixed? (You do not have to write code, just use English.)

Original:

import java.util.*;
import java.lang.*;
import java.io.*;


class Foopadoop
{
public static int counter = 0;
public static void main(String[] args) throws Exception {
    Runnable r = new Runnable() {
        public void run() {
            while(true){
                counter++;
            }
        }
    };
    Thread t1 = new Thread(r);
    Thread t2 = new Thread(r);
    t1.start();
    t2.start();
}
}

Mine, I added a semaphore but I'm not sure if I'm doing it right or am I suppose to use a lock.

import java.util.*;
import java.lang.*;
import java.io.*;
import java.util.concurrent.Semaphore;

class Foopadoop
{
public static int counter = 0;
Semaphore lock = new Semaphore(0);
public static void main(String[] args) throws Exception {
    Runnable r = new Runnable() {
        try{public void run() {
            while(true){
                counter++;
                lock.acquire();
            }
        }
       }finally{
         lock.release();
        }
    };
    Thread t1 = new Thread(r);
    Thread t2 = new Thread(r);
    t1.start();
    t2.start();
}
}
0

2 Answers 2

4

That's not how you use a Semaphore.

You acquire it before you access the shared resource, and release it after:

while (true) {
  try {
    lock.acquire();
    counter++;
  } finally {
    lock.release();
  }
}

Since you acquire first, you will also need at least 1 permit, otherwise there is nothing to acquire:

static Semaphore lock = new Semaphore(1);

A synchronized block is easier than a Semaphore:

while (true) {
  synchronized (Foopadoop.class) {
    counter++;
  }
}

or an AtomicInteger:

static AtomicInteger counter = new AtomicInteger();

// ...

while (true) {
  counter.getAndIncrement();
}
Sign up to request clarification or add additional context in comments.

5 Comments

If you were to explain it why the thing doesn't work would it be - Is the code wrong because The threads are multi initializing the thread thus counter = 0; but the method ran twice?
No, it is wrong because you access the shared resource before you acquire the semaphore. The point of the semaphore is to enforce mutually-exclusive access to the variable. And also because you acquire multiple times before releasing. And because you're trying to acquire a semaphore with no permits.
I mean the original question, not my edition of the code.
In the original version, counter is only initialized once, when the class is loaded. The problem is that updates to counter are not guaranteed to be visible between threads; additionally, its value is not guaranteed to be incremented atomically.
so to resolve If I say this would it be a valid answer/solution: We need to use a lock or semaphore to block one of the threads, so the counter will be initialized twice?
0

Also you can add Thread.sleep(ms) inside the while loop, so that it will pause the current thread for some time, & start executing other threads. Otherwise the current thread might run in a selfish manner (selfish thread).

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.