How can I adjust fairness between given k threads to generate some output?
In other words imagine we have k threads printing "1" and n threads printing "2".
Now how can we put fairness between threads so each thread print(for example "1") as much as other (k - 1) print(for example "1").and the same for n thread printing "2".
Before you create the threads, create an array[0..numThreads-1] of empty semaphores, one for each thread you are going to create. Signal to each thread on its creation an incrementing semaphore index, 0..numThreads-1.
In the thread function, have it wait on its semaphore[index], then print something, then signal the [(index+1) mod numThreads] semaphore, then loop round to wait on the semaphore[index] again.
Once you have done that, nothing should happen at all.
Throw in one semaphore unit, anywhere.
well, I understand a little, you could make that a thread print a number if you send that number to their constructor.
for example:
public class MyThread extends Thread
{
int number = 0;
public MyThread(int number) {
this.number = number;
}
#Override
public void run()
{
while(true) {
System.out.println(this.number);
this.sleep(1000);//control exception
}
}
}
then in your main
public class Main() {
public static void main(String[] args) {
int k = 10
for(int i = 0; i < k; k++) {
MyThread mt = new MyThread(1);
mt.start();
mt.join();
}
}
}
You should repeat a similar form for Thread printing 2
Related
I have a small project to synchronize multiple (two classes: ships, cars with a few instances with shared bufor class called Harbour) threads at the same time. They will be performing certain action on it. But I can't start with that until I synchronized the threads named "cars" in the Harbour. The Harbour has limited capacity and if this capacity is reached the "car" threads should be waiting until they will get signal that there's a free space to enter. I've used Retrant Lock with Condition but it doesn't work as I think.
public class Harbour {
final Lock protectNr;
final Condition protectNrCon;
int capacity;
int nrOfCars;
public Harbour(int capacity) {
this.capacity = capacity;
this.protectNr = new ReentrantLock();
this.protectNrCon = protectNr.newCondition();
}
public void carEnterHarbour(String name) {
try {
protectNr.lock();
if (this.nrOfCars == this.capacity)
protectNrCon.await();
nrOfCars++;
System.out.println(name + " enters");
System.out.println("Number of cars:" + this.nrOfCars);
protectNr.unlock();
} catch (InterruptedException e) {
System.out.println("Error");
}
}
public void carLeavingHarbour(String name) {
try {
protectNr.lock();
this.nrOfCars--;
protectNrCon.signal();
System.out.println(name + " leaving");
System.out.println("Number of cars:" + this.nrOfCars);
} finally {
protectNr.unlock();
}
}
}
public class Car extends Thread {
Harbour harbour;
public Car(Harbour harbour, String name) {
super(name);
this.harbour = harbour;
}
public void run() {
for (int i = 0; i < 10; i++) {
harbour.carEnterHarbour(getName());
harbour.carLeavingHarbour(getName());
}
}
}
public class Test {
public static void main(String[] args) throws InterruptedException {
int harbourCapacity = 20;
final Harbour harbour = new Harbour(harbourCapacity);
int nrOfCars = 500;
Car[] cars = new Car[nrOfCars];
for (int i = 0; i < nrOfCars; i++)
cars[i] = new Car(harbour, "Car-" + i);
for (int i = 0; i < nrOfCars; i++)
cars[i].start();
for (int i = 0; i < nrOfCars; i++)
cars[i].join();
}
}
What I was expecting after executing this code:
Car-386 leaving
Number of cars:**19**
Car-300 enters
Number of cars:**20**
Car-300 leaving
Number of cars:**19**
What I got:
Car-386 leaving
Number of cars:**20**
Car-300 enters
Number of cars:**21**
Car-295 enters
Number of cars:**22**
I also try to change int capacity to volatile int capacity and add some busy waiting but didn't work at all.
It looks like Threads are not block on Condition and I wonder why is this happening?
The documentation for Condition warns that spurious wakeups might occur (emphasis mine):
When waiting upon a Condition, a "spurious wakeup" is permitted to occur, in general, as a concession to the underlying platform semantics. This has little practical impact on most application programs as a Condition should always be waited upon in a loop, testing the state predicate that is being waited for. An implementation is free to remove the possibility of spurious wakeups but it is recommended that applications programmers always assume that they can occur and so always wait in a loop.
Your code doesn't honor that warning.
Your carEnterHarbour() must take this possibility of spurious wakeups into account and needs
while(this.nrOfCars == this.capacity){
protectNrCon.await();
}
instead of the simple if statement.
Depending on your requirements it might be easier to use a Semaphore:
public class Harbour {
final Semaphore slots;
public Harbour(int capacity){
this.slots = new Semaphore(capacity);
}
public void carEnterHarbour(String name) {
try{
slots.acquire();
}catch (InterruptedException e){
System.out.println("Error");
}
}
public void carLeavingHarbour(String name) {
slots.release();
}
}
Note that when using a Semaphore you don't have those locks in place when entering / leaving the Harbour and therefore it is difficult to get that ordered "car entering" / "car leaving" output together with the number of currently available slots.
In the carEnterHarbour method, you are calling await() on the protectNrCon condition, which causes the current thread to wait until it is signaled. However, you are not calling signal() anywhere in the carEnterHarbour method. This means that once a thread enters the if block, it will always wait indefinitely on the condition.
You should consider calling signal() on the protectNrCon condition after you increment nrOfCars and print the message, so that other threads waiting on the condition can be unblocked.
Additionally, you should call await() in a loop to ensure that the thread waits until the condition is true, rather than waiting indefinitely. Here is an example of how you can modify the carEnterHarbour method:
public void carEnterHarbour(String name) {
try {
protectNr.lock();
while (this.nrOfCars == this.capacity) {
protectNrCon.await();
}
nrOfCars++;
System.out.println(name+" enters");
System.out.println("Number of cars:" + this.nrOfCars);
protectNrCon.signal();
} catch (InterruptedException e) {
System.out.println("Error");
} finally {
protectNr.unlock();
}
}
This question already has answers here:
How threads are executed in the memory?
(2 answers)
Closed 2 years ago.
This is a simplified version of the problem. Given n number of threads, each printing a constant number all the time. For example, Thread-1 should always print 1, Thread-2 should always print 2 and so on...
How to ensure, the threads are executed in order i.e. the output should be as below:
Thread-1: 1
Thread-2: 2
Thread-3: 3
.
.
.
Thread-n: n
I have a naïve solution to do it through wait()/notify() but I guess there might be a better solution than that. Perhaps, using Semaphore maybe? I don't know.
Update:
Based on the answers received, I think I was not very clear. There are some constraints:
All threads should start at once (assume we don't really have control on that)
Once all the threads start, there should be some sort of communication between the threads to execute in order.
This sequentially execution of thread can be handled beautifully using Thread.join() method. To handle it properly, you may have to create MyRunnable(or, use any name you prefer) which implements Runnable interface. Inside MyRunnable, you can inject a parent Thread, and call parent.join() at top of MyRunnable.run() method. The code is given below:
public class SequentialThreadsTest {
static class MyRunnable implements Runnable {
static int objCount; // to keep count of sequential object
private int objNum;
private Thread parent; // keep track of parent thread
MyRunnable(Thread parent) {
this.parent = parent;
this.objNum = objCount + 1;
objCount += 1;
}
#Override
public void run() {
try {
if(parent != null) {
parent.join();
}
System.out.println("Thread-" + objNum + ": " + objNum);
} catch(InterruptedException e) {
e.printStackTrace();
// do something else
} finally {
// do what you need to do when thread execution is finished
}
}
}
public static void main(String[] args) {
int n = 10;
Thread parentThread = null;
for(int i=0; i<n; i++) {
Thread thread = new Thread(new MyRunnable(parentThread));
thread.start();
parentThread = thread;
}
}
}
And the output is:
Thread-1: 1
Thread-2: 2
Thread-3: 3
Thread-4: 4
Thread-5: 5
Thread-6: 6
Thread-7: 7
Thread-8: 8
Thread-9: 9
Thread-10: 10
You haven't specified many details, but if you only want serializable thread execution you can wait for previous thread to finish and then print. Something like this:
public static void main(String[] args) {
Thread thread = null;
for (int i = 0; i < 10; i++) {
int index = i;
Thread previousThread = thread;
thread = new Thread(() -> {
if (previousThread != null) {
try {
previousThread.join();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
System.out.println(index);
});
thread.start();
}
}
Try making a queue - this will do exactly what you want. Simply change the value of n to however many threads you have, and add all the threads sequentially (only once). If ever you want to stop the threads from executing, all you have to do is add end to the queue. Obviously, for a larger project, you will need to modify this code a little bit (I would recommend replacing the main method with a class initializer and pass the LinkedBlockingQueue as a pre-built argument)
import java.util.concurrent.LinkedBlockingQueue;
public class HelloWorld{
private static int n = 2;
private static LinkedBlockingQueue<Thread> queue = new LinkedBlockingQueue<>(n+1);
static Thread a = new Thread(()->{
System.out.print("a");
});
static Thread b = new Thread(()->{
System.out.print("b");
});
static Thread end = new Thread(()->{
break_ = true;
});
public static final int END = 20;//this and the counter are just here so the code doesn't run forever
public static volatile int i = 0;
public static volatile boolean break_ = false;
public static void main(String []args){
queue.add(a);
queue.add(b);
//queue.add(end);
outerloop:
while(true){
Thread toBeRun = queue.poll();
try{
toBeRun.run();
queue.add(toBeRun);
i++;
if(i>=END || break_){//i>=END does not need to be here, it's just to stop it from running forever in this example
break;
}
}catch(NullPointerException e){
break;
}
}
}
}
Note: This uses java 8 lambdas. If you're using an older version of java, you will need to create the threads using the run method.
I have two threads doing calculation on a common variable "n", one thread increase "n" each time, another decrease "n" each time, when I am not using volatile keyword on this variable, something I cannot understand happens, sb there please help explain, the snippet is like follow:
public class TwoThreads {
private static int n = 0;
private static int called = 0;
public static void main(String[] args) {
for (int i = 0; i < 1000; i++) {
n = 0;
called = 0;
TwoThreads two = new TwoThreads();
Inc inc = two.new Inc();
Dec dec = two.new Dec();
Thread t = new Thread(inc);
t.start();
t = new Thread(dec);
t.start();
while (called != 2) {
//System.out.println("----");
}
System.out.println(n);
}
}
private synchronized void inc() {
n++;
called++;
}
private synchronized void dec() {
n--;
called++;
}
class Inc implements Runnable {
#Override
public void run() {
inc();
}
}
class Dec implements Runnable {
#Override
public void run() {
dec();
}
}
}
1) What I am expecting is "n=0,called=2" after execution, but chances are the main thread can be blocked in the while loop;
2) But when I uncomment this line, the program when as expected:
//System.out.println("----");
3) I know I should use "volatile" on "called", but I cannot explain why the above happens;
4) "called" is "read and load" in working memory of specific thread, but why it's not "store and write" back into main thread after "long" while loop, if it's not, why a simple "print" line can make such a difference
You have synchronized writing of data (in inc and dec), but not reading of data (in main). BOTH should be synchronized to get predictable effects. Otherwise, chances are that main never "sees" the changes done by inc and dec.
You don't know where exactly called++ will be executed, your main thread will continue to born new threads which will make mutual exclusion, I mean only one thread can make called++ in each time because methods are synchronized, and you don't know each exactly thread will be it. May be two times will performed n++ or n--, you don't know this, may be ten times will performed n++ while main thread reach your condition.
and try to read about data race
while (called != 2) {
//System.out.println("----");
}
//.. place for data race, n can be changed
System.out.println(n);
You need to synchronize access to called here:
while (called != 2) {
//System.out.println("----");
}
I sugest to add getCalled method
private synchronized int getCalled() {
return called;
}
and replace called != 2 with getCalled() != 2
If you interested in why this problem occure you can read about visibility in context of java memory model.
edit: 1.) Why is "globalCounter" synchronized , but not "Thread.currentThread().getId()"
2.) Can I assign a calculation to each thread? how? Can i work with the results?
public class Hauptprogramm {
public static final int MAX_THREADS = 10;
public static int globalCounter;
public static Integer syncObject = new Integer(0);
public static void main(String[] args) {
ExecutorService threadPool = Executors.newFixedThreadPool(MAX_THREADS);
for (int i = 0; i < MAX_THREADS; i++) {
threadPool.submit(new Runnable() {
public void run() {
synchronized (syncObject) {
globalCounter++;
System.out.println(globalCounter);
System.out.println(Thread.currentThread().getId());
try {
Thread.sleep(10);
} catch (InterruptedException e) {
}
}
}});
}
threadPool.shutdown();
}
}
1.) Why is "globalCounter" synchronized , but not "Thread.currentThread().getId()"
I can answer why globalCounter is synchronized. To avoid data race and race condition.
In case if it is not synchronized - globalCounter++ computation is a three step process (Read-Modify-Write) -
Read the current value of globalCounter varaible.
Modify its value.
Write/ Assign the modified value back to the globalCounter.
In the absence of synchronization in multi threaded environment, there is a possibility that a thread might read/ modifies the value of globalCounter when another thread is in the mid of this 3 step process.
This can result into thread/s reading stale values or loss of update count.
2) Can I assign a calculation to each thread? how? Can i work with the results?
This is possible. You can look into Future/ FutureTask to work with the result
I am taking a book to do some mock test, I have found this question:
import java.util.concurrent.atomic.AtomicInteger;
class AtomicVariableTest {
private static AtomicInteger counter = new AtomicInteger(0);
static class Decrementer extends Thread {
public void run() {
counter.decrementAndGet(); // #1
}
}
static class Incrementer extends Thread {
public void run() {
counter.incrementAndGet(); // #2
}
}
public static void main(String[] args) {
for (int i = 0; i < 5; i++) {
new Incrementer().start();
new Decrementer().start();
}
System.out.println(counter);
}
}
The answer:
This program will always print 0.
But I think there is no guarantee that the threads will have completed when it prints the counter value.
I mean, most of the time it will return 0, but if you are strict with the theory there is no guarantee of this.
Am I correct?
There is guaranteed. And there is not guaranteed. There is no middle ground.
In this case there is no guarantee that the result is always zero. This is because the threads are not joined - and might never even have actually ran before the print!
For example, among other permutations, the sequence this code could have executed is:
counter.decrementAndGet(); // #1
System.out.println(counter); // Main thread
counter.incrementAndGet(); // #2
// (and so on, at some arbitrary point after the print)
Avoiding such undesired interleaving/execution is handled in Java (as per the JLS) under happens-before relationships.
If the threads were joined (to the thread with the print) then a happens-before would have been established - in this case that would mean that the threads started and finished running - and the result would be guarantee to be zero.
public static void main(String[] args) {
final List<Thread> threads = new ArrayList<>();
for (int i = 0; i < 5; i++) {
final new Incrementer i = new Incrementer();
threads.add(i);
i.start();
final new Decrementer d = new Decrementer();
threads.add(d);
d.start();
}
for (final Thread t : threads) { t.join(); }
System.out.println(counter);
}
See one of the many duplicates: Wait until child threads completed : Java
And this is why you use the ExecutorService or ExecutorCompletionService and never deal with thread management manually because it is extremely error prone otherwise.