I wrote an example trying to understand volatile.
public class VolatileExample {
private volatile boolean close = false;
public void shutdown() {
close = true;
}
public void work(){
Thread t1 = new Thread(new Runnable(){
public void run(){
while (!close) {
}
}
});
Thread t2 = new Thread(new Runnable(){
public void run(){
while (!close) {
shutdown();
}
}
});
t1.start();
t2.start();
try {
t1.join();
t2.join();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
public static void main(String[] args){
VolatileExample volatileExample = new VolatileExample();
volatileExample.work();
}
}
it did stop as I expected. However, when I took the volatile away from the close tag, I have tried a lot of times---I expect the program will not stop because the thread t1 cannot see the change made by thread t2 on the close variable, but the programs ended successfully everytime. So I am confused, now that we can do it without volatile, what is volatile used for? Or can you give a better example that can make a difference between using volatile and not using volatile?
Thank you!
The memory model says only that changes to non- volatile fields may not be visible in other threads.
Perhaps your runtime environment was in a cooperative mood.
Changes to nonvolatile fields are sometimes visible to other threads, and sometimes not. How long they take to be visible to other threads can vary by orders of magnitude depending on what other processing the machine is doing, the number of processor chips and cores on the machine, the architecture of the cache memory on the machine, etc.
Ultimately, though, it comes down to this: buggy concurrency code can succeed the first 999,999 times, and fail on the millionth time. That often means it passes all tests, then fails in production when things really matter. For that reason, it's important when writing concurrent code that one make the best possible effort to ensure the code is correct - and that means using volatile for variables accessed from multiple threads even when it doesn't seem to make a difference in testing.
Related
I tested the below piece of code on HotSpot and Android ART, but with different results.
On HotSpot, MyThread never gets the updated isRunning, it get isRunning = true always...
But when I test it on ART, MyThread can get the updated isRunning and exit loop normally...
As I know about java happens-before rule, an non-volatile is not visible across multi-thread, just like the behave of the code below on Hotspot.
Does it depends on VM implementation? Or maybe Android ART has their own optimization?
class MyThread extends Thread {
public boolean isRunning = true;
#Override
public void run() {
System.out.println("MyThread running");
while (true) {
if (isRunning == false) break;
}
System.out.println("MyThread exit");
}
}
public class RunThread{
public static void main(String[] args) {
new RunThread().runMain();
}
public void runMain() {
MyThread thread = new MyThread();
try {
thread.start();
Thread.sleep(500);
thread.isRunning = false;
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
an non-volatile is not visible across multi-thread, just like the behave of the code below on Hotspot.
That's not quite right. A non-volatile write, absent any additional synchronization or other happens-before relationship, is not guaranteed to be visible to a read of that same variable in another thread. It's allowed to be visible, though. I've absolutely seen HotSpot make writes visible across threads despite no happens-before relationship. Based on my experience with this, I suspect that if you remove that Thread.sleep call in your code, HotSpot will also make the write to isRunning visible to the thread, despite the lack of any happens-before relationship between the write and the read.
You're definitely right that it's VM-specific, and it's possibly/likely even processor architecture–specific, since different architectures may give different amounts of synchronization for "free", or have different amounts of cache that affect whether a memory address is read from a core's cache or fetched from main memory.
In summary, you should never rely on this sort of behavior working any specific way on any specific VM—it's liable to change without warning.
I am not very good at multithreading and am baffled by this code:
public class Main {
public static void main(String... args) throws Exception {
new Thread(Main::test).start();
}
private static synchronized void test() {
new Thread(Main::test).start();
System.out.println("TEST");
}
}
Can it result in a deadlock or not? If so, then why have I not been able to get it to deadlock? My thinking is, thread 1 acquires lock on test(), then another thread, created in test() tries to acquire it and they should be waiting on each other. But they aren't, why not?
I know, that adding join() in test() will make it result in a deadlock, but how come the example below doesn't use joins and deadlocks?
This code results in a deadlock literally every time I run it:
public class Main {
public static void main(String... args) {
new Thread(Main::test).start();
new Thread(Main::test2).start();
}
private static void test() {
synchronized (Integer.class) {
try {
Thread.sleep(1);
} catch (Exception e) {
}
synchronized (Float.class) {
System.out.println("Acquired float");
}
}
}
private static void test2() {
synchronized (Float.class) {
try {
Thread.sleep(1);
} catch (Exception e) {
}
synchronized (Integer.class) {
System.out.println("Acquired integer");
}
}
}
}
No, the code in the first example cannot deadlock. The newly started threads will simply wait until the previous thread exits the method to acquire the lock.
The code in the second example deadlocks because the locks are acquired in opposite order and because of the sleeps are reliably going to block each other.
When you're at the phase where you're first learning how to think about concurrency and related problems, I would very much recommend using physical props to keep your thoughts and hypotheses clear and explicit.
For example, grab a A3 sheet of paper, set up a "race track" where you use something like Monopoly pieces to signify what you're doing in your code, what you expect to happen, and what your experiments show actually happens.
When your experiments don't work out, take a small piece of the beginning first, and verify it. Then add some more, and so on.
It helps if you read about how actual computers (not the CS ideal or conceptual computers) currently work. How the CPU gets data out of the main memory into its cache. How two or three CPUs decide which one of them can handle data in one cache line at a time. Then, how the Java Memory Model needs you to write your source code so that the JVM knows what you actually mean to happen.
My application has 1 global driver, which is responsible for doing the low-level work.
I then have 2 threads, both of which use infinite loops to get some work done. My question is how to allow 1 thread to use the driver as much as possible, but giving a chance to the second thread to use it when necessary.
To elaborate, the code I have is as follows:
public class Game {
private static final Object LOCK = new Object();
private static final Logger LOGGER = Logger.getLogger(Game.class);
private WebDriverController controller;
public Game(WebDriverController controler) {
this.controller = controller;
}
public void startThreadA() {
new Thread(new Runnable() {
#Override
public void run() {
while (true) {
synchronized (LOCK) {
controller.doSomethingA();
}
}
}
}).start();
}
public void startThreadB() {
new Thread(new Runnable() {
#Override
public void run() {
while (true) {
...
...
synchronized (LOCK) {
controller.doSomethingB();
}
...
...
}
}
}).start();
}
}
The logic is to allow the first thread to execute doSomethingA() as much as possible, with the second thread only acquiring the lock to complete little tasks and then giving the lock back to the first thread.
Using this code, the first thread will continuously use the controller to do what it needs to do, whereas the second thread gets stuck waiting at its synchronized block. The way I have currently fixed this is by adding a pause to the first thread, to give the second thread a chance to acquire the lock, as follows:
public void startThreadA() {
new Thread(new Runnable() {
#Override
public void run() {
while (true) {
synchronized (LOCK) {
controller.doSomethingA();
}
try {
Thread.sleep(1);
} catch (InterruptedException e) {
LOGGER.error(null, e);
}
}
}
}).start();
}
This does work exactly as intended, but it doesn't seem right. I'm not happy with the manual pause after each iteration, especially if the second thread does not need the lock as it's wasting time.
What do I replace the pause with to make this more efficient?
Why you use synchronized in run()? Use synchronized or Lock in your methods in WebDriverController.
public void doSomeThingA(){
lock.lock();
try {
//your stuff
} finally {
lock.unlock();
}
}
And in run method of Thread invoke these methods.
I think you are approaching this from the wrong direction, as in your current setup 99.999% of the time thread A calls for a monitor the processing time is wasted. However as I do not have enough details about your actual problem, here is a quick solution using a ReentrantLock with fair scheduling (FIFO):
protected final ReentrantLock lock = new ReentrantLock(true); // fair scheduling
public void functionA() {
lock.lock();
try {
controller.functionA();
} finally {
lock.unlock();
}
}
public void functionB() {
lock.lock();
try {
controller.functionB();
} finally {
lock.unlock();
}
}
Explanation:
If Thread A is currently holding the lock and Thread B calls, B is guaranteed to receive the monitor right after A releases it, even if A immediately (before any thread switch occurs) calls for it again.
There are a few options here. The best bet in this instance is likely to be remove the responsibility of deciding when to do work from the threads and instead, waiting for an event from a monitor to release the threads to do work. You can then schedule the work in whichever ratio is best suited to the purpose.
Alternatively, remove the lack of thread safety from your controller code.
Assuming that above thread organization is the best way to go for your particular case, your problem is that first thread holds the lock too long, thus starving the second one.
You can check if doSomethingA function really needs locked driver all the time while it is being executed (in most cases it doesn't), and if not split it into multiple smaller execution blocks, some of which hold the lock while other's don't. This will create more time for second thread to kick in when it needs to.
If that cannot be done then you really need to rethink your app, because you have created a resource bottleneck.
It looks like Thread.yield () is what you are looking for.
I am facing one issue related to multithreading because of shared code. I want to avoid syncronization. I saw so many threads related to AtomicInteger & Semaphore. But havn't got clear idea about what way and how exactly it is better option than synchronization.
Here is my simple code which i want to make thread safe.
Class to create thread.
public class ThreadCheck implements Runnable {
TestStaticVar var = new TestStaticVar();
#Override
public void run() {
// TODO Auto-generated method stub
try {
var.holdOn();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
public static void main(String args[]) {
ThreadCheck t = new ThreadCheck();
Thread t1 = new Thread(t);
Thread t2 = new Thread(t);
t1.setName("A");
t1.start();
t2.setName("B");
t2.start();
}}
Class to be executed by multiple threads.
public class TestStaticVar {
Semaphore sem = new Semaphore(1);
public void holdOn() throws InterruptedException{
sem.acquire();
System.out.println("Inside Hold on....."+Thread.currentThread().getName()+"==> ");//+i.get());
try {
for (long i=0; i<Integer.MAX_VALUE; i++) {
}
System.out.println(var1.toString());
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
System.out.println("Finished Hold on===="+Thread.currentThread().getName());
sem.release(1);
System.out.println("Execution Completed by =====> "+Thread.currentThread().getName());
}}
Any help is highly appriciate.
Thanks,
Rajesh
One way to avoid synchronization is to make every resource immutable which would be accessed by multiple threads. Making class/object immutable makes sure its threadsafe.
How you avoid synchronization depending on the situation. As your situation is contrived and doesn't do anything which needs locking, the simplest thing to do is remove the lock i.e. only lock when you need to. (Also remove the long loop which doesn't do anything) Then your application will run much faster.
The two main reasons to try to avoid synchronize blocks are performance and protecting yourself from deadlocks.
Using the synchronize keyword involves performance overhead in setting up the locks and protecting the synchronized operation. While there is a performance penalty for calling a synchronized block, there's a much bigger hit that gets taken when the JVM has to manage resource contention for that block.
The classes in java.util.concurrent.atomic can use machine level atomic instructions rather than locking, making them much faster than code that would use locks. See the javadoc for the package for more information on how that works.
Also, as u3050 mentioned, avoiding mutable shared state goes a long way to preventing the need for synchronization.
Maybe this question has been asked many times before, but I never found a satisfying answer.
The problem:
I have to simulate a process scheduler, using the round robin strategy. I'm using threads to simulate processes and multiprogramming; everything works fine with the JVM managing the threads. But the thing is that now I want to have control of all the threads so that I can run each thread alone by a certain quantum (or time), just like real OS processes schedulers.
What I'm thinking to do:
I want have a list of all threads, as I iterate the list I want to execute each thread for their corresponding quantum, but as soon the time's up I want to pause that thread indefinitely until all threads in the list are executed and then when I reach the same thread again resume it and so on.
The question:
So is their a way, without using deprecated methods stop(), suspend(), or resume(), to have this control over threads?
Yes, there is:
Object.wait( ), Object.notify() and a bunch of other much nicer synchronization primitives in java.util.concurrent.
Who said Java is not low level enough?
Here is my 3 minute solution. I hope it fits your needs.
import java.util.ArrayList;
import java.util.List;
public class ThreadScheduler {
private List<RoundRobinProcess> threadList
= new ArrayList<RoundRobinProcess>();
public ThreadScheduler(){
for (int i = 0 ; i < 100 ; i++){
threadList.add(new RoundRobinProcess());
new Thread(threadList.get(i)).start();
}
}
private class RoundRobinProcess implements Runnable{
private final Object lock = new Object();
private volatile boolean suspend = false , stopped = false;
#Override
public void run() {
while(!stopped){
while (!suspend){
// do work
}
synchronized (lock){
try {
lock.wait();
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
return;
}
}
}
}
public void suspend(){
suspend = true;
}
public void stop(){
suspend = true;stopped = true;
synchronized (lock){
lock.notifyAll();
}
}
public void resume(){
suspend = false;
synchronized (lock){
lock.notifyAll();
}
}
}
}
Please note that "do work" should not be blocking.
Short answer: no. You don't get to implement a thread scheduler in Java, as it doesn't operate at a low enough level.
If you really do intend to implement a process scheduler, I would expect you to need to hook into the underlying operating system calls, and as such I doubt this will ever be a good idea (if remotely possible) in Java. At the very least, you wouldn't be able to use java.lang.Thread to represent the running threads so it may as well all be done in a lower-level language like C.