This question already has answers here:
Mutually exclusive methods
(5 answers)
Closed 6 years ago.
I am looking for a way to avoid the two methods from running concurrently, but not stopping one (or both) of them for running concurrently on their own. For example, in the code below, I must have method A run concurrently on the same object, but method B should block until there are no threads running Method A. Similarly, A should block if B is running on any thread and B can run concurrently with itself.
public void A() // calls from different threads on the same object allowed
{
....
} // A should only block if B is running
public void B() // calls from different threads on the same object allowed
{
....
} //B should only block if A is active
You could do something simple with an AtomicInteger, though it wouldn't be efficient.
static final AtomicInteger counter = new AtomicInteger();
public void methodA() {
for(;;) {
int v = counter.get();
if (v >= 0 && counter.compareAndSwap(v, v + 1))
break;
Thread.yield();
}
try {
// do something
} finally {
counter.decrementAndGet();
}
}
public void methodB() {
for(;;) {
int v = counter.get();
if (v <= 0 && counter.compareAndSwap(v, v - 1))
break;
Thread.yield();
}
try {
// do something
} finally {
counter.incrementAndGet();
}
}
Related
This question already has answers here:
Java 8: Parallel FOR loop
(4 answers)
Closed 4 years ago.
Is there a easy way to parallelise a foreach loop in java 8 using some library stuff?
void someFunction(SomeType stuff, SomeType andStuff) {
for (Object object : lotsOfObjects)
object.doSomethingThatCanBeDoneInParallel(stuff, andStuff);
}
Multithreading is kinda painful and time consuming so i wonder if there is a simpler way to do the above using some library.
thanks.
edited in 3/06/2018
ExecutorServices is very handy indeed, I can't use shutdown() to wait because I run the thing every frame and create a new ExecutorServices every frame would be too expensive.
I ended up writing a class to parallelize a fori loop and I thought I share it with other newbies like me.
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.atomic.AtomicBoolean;
public class ParallelForI {
public ParallelForI(int numberOfThread) {
NUMBER_OF_THREAD = numberOfThread;
executorService = Executors.newFixedThreadPool(NUMBER_OF_THREAD);
finished = new AtomicBoolean[NUMBER_OF_THREAD];
for (int i = 0; i < finished.length; i++)
finished[i] = new AtomicBoolean(true);
// true is better for waitForLastRun before any run.
}
private ExecutorService executorService;
private final int NUMBER_OF_THREAD;
private AtomicBoolean[] finished;
public void waitForLastRun() {
synchronized (this) {
/* synchronized outside the loop so other thread
can't notify when it's not waiting. */
for (int i = 0; i < NUMBER_OF_THREAD; i++) {
if (!finished[i].get()) {
i = -1;
try {
this.wait(); //
} catch (InterruptedException e) {
// do nothing and move one.
}
}
}
}
}
public void run(FunctionForI functionForI, final int MAX_I) {
for (AtomicBoolean finished : finished)
finished.set(false); // just started
for (int i = 0; i < NUMBER_OF_THREAD; i++) {
final int threadNumber = i;
executorService.submit(new Runnable() {
#Override // use lambda if you have java 8 or above
public void run() {
int iInitial = threadNumber * MAX_I / NUMBER_OF_THREAD;
int iSmallerThan;
if (threadNumber == NUMBER_OF_THREAD - 1) // last thread
iSmallerThan = MAX_I;
else
iSmallerThan = (threadNumber + 1) * MAX_I / NUMBER_OF_THREAD;
for (int i1 = iInitial; i1 < iSmallerThan; i1++) {
functionForI.run(i1);
}
finished[threadNumber].set(true);
synchronized (this) {
this.notify();
}
}
});
}
}
public interface FunctionForI {
void run(int i);
}
}
And this is the way to use it:
void someFunction(final SomeType stuff, final SomeType andStuff) {
ParallelForI parallelForI = new parallelForI(numberOfThread);
// swap numberOfThread with a suitable int
parallelForI.run(new ParallelForI.FunctionForI() {
#Override // use lambda if you have java 8 or above
public void run(int i) {
lotsOfObjects[i].doSomethingThatCanBeDoneInParallel(stuff, andStuff);
// don't have to be array.
}
}, lotsOfObjects.length); // again, don't have to be array
parallellForI.waitForLastRun(); // put this where ever you want
// You can even put this before parallelForI.run().
// Although it doesn't make sense to do that...
// Unlike shutdown() waitForLastRun() will not cause parallelForI to reject future task.
}
A solution could be to launch every task in a Thread as follows:
new Thread(() -> object.doSomethingThatCanBeDoneInParallel(stuff, andStuff)).start();
but this is not a relevant solution as Thread creation is costly, so there are mechanisms and tools to help you: the Executors class to build some pools.
Once you have the instance that will manage this, you provide it with tasks, which will run in parallel, on the number of threads you choose:
void someFunction(SomeType stuff, SomeType andStuff) {
ExecutorService exe = Executors.newFixedThreadPool(4); // 4 can be changed of course
for (Object object : lotsOfObjects) {
exe.submit(() -> object.doSomethingThatCanBeDoneInParallel(stuff, andStuff));
}
// Following lines are optional, depending if you need to wait until all tasks are finished or not
exe.shutdown();
try {
exe.awaitTermination(Long.MAX_VALUE, TimeUnit.NANOSECONDS);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
Use parallel streams. But this is not an universal solution.
For loops in java are inherently serial. There is no way to do such thing with them. With the introduction of streams though, you can parallelize the operations on a collection using them.
This question already has an answer here:
Loop doesn't see value changed by other thread without a print statement
(1 answer)
Closed 5 years ago.
I am now reading 《effective Java》 and meeting a confusion.
For code 1 (java8) :
public class StopThreadTest {
private static Boolean stopRequest = false;
public static void main(String[] args) throws InterruptedException {
new Thread(()->{
int i = 0;
while (!stopRequest) {
i++;
//System.out.println("i: " + i);
}
}).start();
TimeUnit.SECONDS.sleep(1);
stopRequest = true;
}
}
the program never terminates.
For code 2(java8):
public class StopThreadTest {
private static Boolean stopRequest = false;
public static void main(String[] args) throws InterruptedException {
new Thread(()->{
int i = 0;
while (!stopRequest) {
i++;
System.out.println("i: " + i);
}
}).start();
TimeUnit.SECONDS.sleep(1);
stopRequest = true;
}
}
Just adding System.out.println(), the program run about 1 second.
Can anybody tell me why?
System.out.println() is synchronized, removing the visibility issues with the original code. Without it, the thread can use its cached value of stopRequest and keep on running, but when println() is involved, caches are flushed and the modified value can be seen.
From PrintStream.println(String x)
synchronized (this) {
print(x);
newLine();
}
Note that this is a side-effect only. It explains the difference in behaviour, but it's not something you can rely on for correct functionality of code.
Does it continue executing immediately after where it called wait()? Does it start all the way from the beginning of the service method?
A passage from Stephen Hartley's Concurrent Programming: The Java Programming Language had this to say about the matter, which I'm not sure if I understand entirely:
It is not possible with this notification scheme to wait in the middle of a synchronized monitor service method for a signal and then continue executing inside the monitor service method at that point after receiving the signal.
The notification scheme it is referring to is an implementation of the solution to the Readers and Writers problem using notification objects.
Here is a snippet of code of that solution (I'm only showing methods related to Readers):
private int numReaders = 0;
private boolean isWriting = false;
private Vector waitingReaders = new Vector();
private Vector waitingWriters = new Vector();
public void startRead(int i) {
Object convey = new Object();
synchronized (convey) {
if (cannotReadNow(convey))
try { convey.wait(); }
catch (InterruptedException e) {}
}
}
private synchronized boolean cannotReadNow(Object convey) {
boolean status;
if (isWriting || waitingWriters.size() > 0) {
waitingReaders.addElement(convey); status = true;
} else {
numReaders++; status = false;
}
return status;
}
public synchronized void endRead(int i) {
numReaders--;
if (numReaders == 0 && waitingWriters.size() > 0) {
synchronized (waitingWriters.elementAt(0)) {
waitingWriters.elementAt(0).notify();
}
waitingWriters.removeElementAt(0);
isWriting = true;
}
}
The reason I'm so confused is the quote above seems to contradict programming practices shown in code samples from the same book.
For example, this is a snippet of code of the Readers and Writers solution using plain monitors, without notification objects
public synchronized void startRead(int i) {
long readerArrivalTime = 0;
if (numWaitingWriters > 0 || numWriters > 0) {
numWaitingWriters++;
readerArrivalTime = age();
while (readerArrivalTime >= startWritingReadersTime)
try {wait();}
catch (InterruptedException e) {}
numWaitingReaders--;
}
numReaders++;
}
If it's not possible for a thread to continue executing where it was blocked by a call to wait(), why is a while-loop used to check for the condition? If every thread that gets blocked and then regains entry to the monitor via a call to startRead() has to begin from the beginning of that method, as the quote above seems to be suggesting, wouldn't an if-statement suffice for checking the condition?
Moreover, how does any of this explain this next quote, which in the book follows immediately after the quote above:
To avoid deadlock, the thread must leave the synchronized method with a return statement before waiting inside the notification object.
If I understood this question... Try this:
public synchronized void startRead(int i) {
long readerArrivalTime = 0;
if (numWaitingWriters > 0 || numWriters > 0) {
numWaitingWriters++;
readerArrivalTime = age();
while (readerArrivalTime >= startWritingReadersTime)
try {wait();}
catch (InterruptedException e) {}
numWaitingReaders--;
}
numReaders++;
}
public synchronized void endRead(int i) {
numReaders--;
if (numReaders == 0 && waitingWriters.size() > 0) {
notify();
waitingWriters.removeElementAt(0);
isWriting = true;
}
}
concreteObject.wait/notify/notifyAll methods can be called only from synchronized(concreteObject) block. If you call their without concreteObject (just wait() or notify()), it's same as this.wait() or this.notify().
Synchronized non static methods are same as synchronized(this) blocks.
I want to write two Threads that increment a number and decrement a number, and a main Thread that determines when the two numbers are equal. For example, one number starts at 0 and the other number starts at 10... When they are both 5, the main Thread should recognize they are equal and print "They meet!".
In this code, the main Thread can't not compare numup and numdown successfully:
public class Number implements Runnable {
public static int numup = 0;
public static int numdown = 10;
public Number() {
}
public static void main(String args[]) {
Number number = new Number();
Thread T1 = new Thread(number, "up");
Thread T2 = new Thread(number, "down");
T1.start();
T2.start();
while (true) {
if (numup == 5 && numdown == 5) {
System.out.println("Meet!");
System.exit(0);
}
}
}
public void run() {
while (true) {
if (Thread.currentThread().getName().equals("up")) {
numup++;
System.out.println(numup);
} else if (Thread.currentThread().getName().equals("down")) {
numdown--;
System.out.println(numdown);
}
try {
Thread.sleep(1000);
} catch (Exception e) {
System.out.println("wake!");
}
}
}
}
The failed result:
1
9
8
2
7
3
6
4
5
5
6
4
7
3
8
2
1
9
However, when I make the main Thread sleep a few milliseconds, it works:
public class Number implements Runnable {
public static int numup = 0;
public static int numdown = 10;
public Number() {
}
public static void main(String args[]) {
Number number = new Number();
Thread T1 = new Thread(number, "up");
Thread T2 = new Thread(number, "down");
T1.start();
T2.start();
while (true) {
try {
Thread.sleep(10);
} catch (Exception e) {
System.out.println(Thread.currentThread().getName() + "was waked!");
}
if (numup == 5 && numdown == 5) {
System.out.println("They Meet!");
System.exit(0);
}
}
}
public void run() {
while (true) {
if (Thread.currentThread().getName().equals("up")) {
numup++;
System.out.println(numup);
} else if (Thread.currentThread().getName().equals("down")) {
numdown--;
System.out.println(numdown);
}
try {
Thread.sleep(1000);
} catch (Exception e) {
System.out.println("wake!");
}
}
}
}
The successful result:
1
9
2
8
3
7
4
6
5
5
They Meet!
Why does the added delay make it work?
This could be because of the CPU cache. When the number thread updates the value of the variable (this goes from its CPU cache to main memory) by then the CPU cache of the corresponding main thread might not have got updated.
So when main thread check's the value of the variable it was still the old value.
You can use Volatile. OR
Use AtomicInteger for these operations.
You can refer to this link.
In a multithreaded application where the threads operate on non-volatile variables, each thread may copy variables from main memory into a CPU cache while working on them, for performance reasons. If your computer contains more than one CPU, each thread may run on a different CPU. That means, that each thread may copy the variables into the CPU cache of different CPUs.
With non-volatile variables there are no guarantees about when the Java Virtual Machine (JVM) reads data from main memory into CPU caches, or writes data from CPU caches to main memory.
Volatile:
public static volatile int numup = 0;
public static volatile int numdown = 10;
Atomic Integer:
import java.util.concurrent.atomic.AtomicInteger;
public class Number implements Runnable {
public static AtomicInteger numup = new AtomicInteger(0);
public static AtomicInteger numdown = new AtomicInteger(10);
public Number() {
}
public static void main(String args[]) {
Number number = new Number();
Thread T1 = new Thread(number, "up");
Thread T2 = new Thread(number, "down");
T1.start();
T2.start();
while (true) {
if (numup.get() == 5 && numdown.get() == 5) {
System.out.println("Meet!");
System.exit(0);
}
}
}
public void run() {
while (true) {
if (Thread.currentThread().getName().equals("up")) {
numup.incrementAndGet();
System.out.println(numup);
} else if (Thread.currentThread().getName().equals("down")) {
numdown.decrementAndGet();
System.out.println(numdown);
}
try {
Thread.sleep(1000);
} catch (Exception e) {
System.out.println("wake!");
}
}
}
}
Quick answer - add volatile modifier to numdown and numup.
Long answer:
Your problem is that other thread can't see that numdown and numup has changed because of couple of reasons:
JVM may optimize and reorder the execution order of bytecode instructions.
Modern processors also do instruction reordering.
The value is cached in processor's cache line (L1, L2, L3 cache level).
So, when you introduce a volatile variable it is guaranteed by java that writes from one thread will have happen-before relationships with reads form another thus making changes visible to the another thread. On more low-level it could introduce a memory barrier
Anyway, it would not fit into the SO answer to explain properly how it's works, but there is a number of excellent resources you could read/watch if you're interested to dive deeper into the topic.
https://zeroturnaround.com/rebellabs/java-memory-model-pragmatics-by-aleksey-shipilev/
Do you ever use the volatile keyword in Java?
http://mechanical-sympathy.blogspot.com/2011/07/memory-barriersfences.html
Cheers!
Interesting one and a good answer given by Yegor. Just to add my observation that the program halts even if you write the if (numup == 5 && numdown == 5) check inside the while loop of the run() method.
In case you want to try out with the volatile keyword.
public static volatile int numup = 0;
public static volatile int numdown = 10;
volatile keyword will ensure that your threads won't cache the value of the variable and will always retrieve it from the main memory.
I am trying to set the difference between synchronized and unsynchronized methods.. I have tried following code
class Counter {
private int counter = 10;
public int getCounter() {
return counter;
}
public synchronized void doIncrementAndDecrement() {
counter++;
keepBusy(500);
counter--;
}
public void keepBusy(int howLong) { // (D)
long curr = System.currentTimeMillis();
while (System.currentTimeMillis() < curr + howLong)
;
}
}
class MyCounterThread extends Thread {
Counter c;
public MyCounterThread(Counter c, String name) {
// TODO Auto-generated constructor stub
super(name);
this.c = c;
start();
}
#Override
public void run() {
for (;;) {
c.doIncrementAndDecrement();
sleepForSometime();
System.out.println(c.getCounter());
}
}
public void sleepForSometime() { // (D)
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
public class UnSynchronizedExapmle {
public static void main(String[] args) throws InterruptedException {
Counter c = new Counter();
MyCounterThread t1 = new MyCounterThread(c, "A");
MyCounterThread t2 = new MyCounterThread(c, "B");
MyCounterThread t3 = new MyCounterThread(c, "C");
}
}
So above i have doIncrementAndDecrement() synchronized method..
So i expected the value of counter should be 10 every time. But this wont happen i have the output is like
10
10
11
10
10
10
10
11
10
10
11
10
11
11
10
10
11
10
11
10
10
10
11
10
10
11
10
So please help me why this happens.. Or any blog/article for explaining difference between synchronized and asynchronized methods
Your getCounter() method is not synchronized. So even though one thread might be locking the method, another thread can still access and print your counter variable
You codes do not synchronized the getCounter method so that System.out.println may output the innerstate of counter. synchronized on method is as same as synchronized(this).
... what difference it make if i write Thread.sleep() in my keepBusy() method.. because the output is quite different in both case.
What it does is to make keepBusy() take a long time, and hence it makes getCounter() wait for a long time.
The difference in the output is due to the synchronization which prevents getCounter() from ever "seeing" the counter in the incremented state.
I mean what do the difference make Thread.sleep() and the above while loop in keepBusy() method make in terms of thread scheduling or locking..
It makes no difference.
For the record, it would bad idea for a real program to have a method like keepBusy() that sleeps in a synchronized method or block. The sleep causes any other thread that is trying to synchronize on the target object to be blocked ... and that's liable to reduce your application's actual parallelism.