/*
This should always produce 0 as output since all three methods increment(), decrement(), value() are thread safe(synchronized). but it is returning 1
*/
class Counter implements Runnable {
private int c = 0;
public synchronized void increment() {
c++;
}
public synchronized void decrement() {
c--;
}
public synchronized int value() {
return c;
}
public void run() {
try {
this.increment();
Thread.sleep(1000);
this.decrement();
Thread.sleep(1000);
this.increment();
Thread.sleep(1000);
this.decrement();
Thread.sleep(1000);
}
catch (InterruptedException e){
return;
}
}
public static void main(String args[]) throws InterruptedException {
Counter c = new Counter();
new Thread(c).start();
new Thread(c).start();
System.out.println(c.value());
}
}
like everyone else said you need to make sure that the treads have finished executing, to do that you need to call join. for example
public static void main(String args[]) throws InterruptedException {
Counter c = new Counter();
Thread t1 = new Thread(c).start();
Thread t2 = new Thread(c).start();
t1.join();
t2.join();
System.out.println(c.value());
}
that should run correctly
There's nothing to control when the main thread is calling value(). It will run as soon as it can acquire a lock on c, even though the other threads are still running.
If you want to wait until the threads are done, call join() on them.
You are reading the value before the threads have finished execution, so it may be well different from zero.
You're not waiting for the threads to complete running, so the result is that the value of c is printed at whatever it is at that second. I bet if you tried it 1000 times, there would be times when it wasn't 1.
IBM has a fair tutorial on the situation you're encountering:
http://publib.boulder.ibm.com/infocenter/iseries/v5r3/index.jsp?topic=/rzahw/rzahwex3rx.htm
Related
This should be an easy problem on multithreading: https://leetcode.com/problems/print-in-order/
"The same instance of Foo will be passed to three different threads. Thread A will call first(), thread B will call second(), and thread C will call third(). Design a mechanism and modify the program to ensure that second() is executed after first(), and third() is executed after second()" And they give this code:
public Foo() {}
public void first(Runnable printFirst) throws InterruptedException {
// printFirst.run() outputs "first". Do not change or remove this line.
printFirst.run();
}
public void second(Runnable printSecond) throws InterruptedException {
// printSecond.run() outputs "second". Do not change or remove this line.
printSecond.run();
}
public void third(Runnable printThird) throws InterruptedException {
// printThird.run() outputs "third". Do not change or remove this line.
printThird.run();
}
**Seems I can solve it using Thread.join as below, but what I don't understand is why they pass the instance of Runnable to each method, and how to properly do it because the below code will print each message twice - once because Thread.start() will invoke the corresponding run() method, and once from calling that method directly. I understand that this is the wrong way to do it, but can't figure out what is the right solution, if we try to utilize the join method. **
public Foo() throws InterruptedException {
Runnable r1 = () -> {
System.out.println("first ");
};
first(r1);
Runnable r2 = () -> {
System.out.println("second ");
};
second(r2);
Runnable r3 = () -> {
System.out.println("third ");
};
third(r3);
Thread t1 = new Thread(r1);
t1.start();
try {
t1.join(); // wait for this thread to finish before starting #2
}
catch(Exception e) {
System.err.println("Thread 1 error");
}
Thread t2 = new Thread(r2);
t2.start();
try {
t2.join();
}
catch(Exception e) {
System.err.println("Thread 2 error");
}
Thread t3 = new Thread(r3);
t3.start();
try {
t3.join();
}
catch(Exception e) {
System.err.println("Thread 3 error");
}
}```
A much easier way would be to just use Semaphore with run, acquire, release methods:
class Foo {
Semaphore runSecond;
Semaphore runThird;
public Foo() {
runSecond = new Semaphore(0);
runThird = new Semaphore(0);
}
public void first(Runnable printFirst) throws InterruptedException {
printFirst.run();
runSecond.release();
}
public void second(Runnable printSecond) throws InterruptedException {
runSecond.acquire();
printSecond.run();
runThird.release();
}
public void third(Runnable printThird) throws InterruptedException {
runThird.acquire();
printThird.run();
}
}
Leetcode is for code challenges, so we should not give complete solutions, because that wouldn't then be a challenge for you.
So here's a hint: Use two CountDownLatch objects, one to inform method second() that method first() is done, the other to inform method third() that method second() is done. Read the documentation to learn how to use it.
While you are reading through the documentation, I recommend you read the package documentation, to learn more about what features are available for handling multi-threaded code.
UPDATE
To better understand the challenge, assume that Leetcode is using a class like this to test the Foo class.
public class Test {
public static void main(String[] args) throws Exception {
Foo foo = new Foo();
Thread t1 = new Thread(() -> call(foo::first, "first,"));
Thread t2 = new Thread(() -> call(foo::second, "second,"));
Thread t3 = new Thread(() -> call(foo::third, "third."));
// Start threads out of order, with delay between them, giving each thread
// enough time to complete, if not adequately coded to ensure execution order.
t2.start();
Thread.sleep(500);
t3.start();
Thread.sleep(500);
t1.start();
// Wait for threads to complete
t2.join();
t3.join();
t1.join();
// At this point, the program output should be "first,second,third."
}
interface FooMethod {
public void call(Runnable printFirst) throws InterruptedException;
}
private static void call(FooMethod method, String text) {
try {
method.call(() -> System.out.print(text));
} catch (InterruptedException e) {
System.out.println(e);
}
}
}
You cannot modify this code, as it is hidden from you. You have to somehow add code to the Foo class to ensure the 3 Runnable objects are called in the correct order.
Simply adding Thread.sleep() calls to the 3 methods is not the right solution, since this should run regardless of how long of a delay might be added between thread starts by this test below.
You have to use some kind of thread synchronization feature, e.g. monitors, Locks, or Synchronizers.
I try to learn something about multithreading and tried myself on a multithreaded counter. For my knowledge, I synchronized the counter variables but I encounter the following problems:
The threads do not take alternating turns
The counter does not count as intended (eg from 337 to 339 or from 344 to 344)
Can anyone please explain, what I did wrong?
Class RunThreads
public class RunThreads {
public static void main(String[] args) {
Thread thread1 = new Thread1();
Thread thread2 = new Thread2();
thread1.start();
thread2.start();
}
}
Class Thread1
public class Thread1 extends Thread {
public void run(){
while (ThreadCount.counter < 1000){
ThreadCount.incrementCounter();
ThreadCount.printCounter(this);
try{
notifyAll();
wait();
}
catch (Exception e){}
}
}
}
class Thread2 (Yes I don't need two separate classes but it makes it easier for me to understand)
public class Thread2 extends Thread {
public void run(){
while (ThreadCount.counter < 1000){
ThreadCount.incrementCounter();
ThreadCount.printCounter(this);
try{
notifyAll();
wait();
}
catch (Exception e){}
}
}
}
class ThreadCount
public class ThreadCount {
public static int counter = 0;
public static synchronized void incrementCounter(){
counter++;
}
public static void decrementCounter(){
counter--;
}
public static synchronized void printCounter(Thread t){;
Output.append(t.getName() + ":" + counter + "\n");
}
}
class Output
public class Output{
public static String value = "";
public static synchronized void append(String s) {
value+=s;
}
}
This demonstrates the pitfalls of swallowing exceptions. If you caught the exceptions in your threads and simply output them, you would observe the following:
java.lang.IllegalMonitorStateException
at java.base/java.lang.Object.notifyAll
at Thread2.run
This will happen when you call wait and notify/notifyAll on an object (the Thread objects, in this case) where you don't hold the lock by means of synchronized.
If you create a common object that both threads synchronize on, and call wait/notifyAll on, you will get what you are observing. For example:
class Thread1 extends Thread {
public void run(){
synchronized (ThreadCount.lockObj) {
while (ThreadCount.counter < 1000) {
ThreadCount.incrementCounter();
ThreadCount.printCounter(this);
try {
ThreadCount.lockObj.notifyAll();
ThreadCount.lockObj.wait();
} catch (Exception e) {
e.printStackTrace();
}
}
}
}
}
The increment and the print are done in two separate operations.
So you can have (for example)
thread1: increment from 342 to 343
thread2: increment from 343 to 344
thread2: print 344
thread1: print 344
Regarding the alternating turns: both threads call wait() and notifyAll() on themselves (so, on two separate objects), and do so without holding their lock, which throws an exception. And since you ignore exceptions, you can't notice the error you made. Never ignore exceptions. Do not catch Exception.
To have alternating turns, the incrementCounter() method could look like this:
private static boolean turn;
public static synchronized void incrementCounter(){
counter++;
printCounter(Thread.currentThread());
turn = !turn;
boolean nextTurn = !turn;
ThreadCount.class.notifyAll();
while (turn != nextTurn) {
try {
ThreadCount.class.wait();
}
catch (InterruptedException e) {
return;
}
}
}
The turn boolean and the while loop might look averkill, but they're in fact necessary if you want your code to work as expected even in case of spurious wakeups.
*Thread1* ThreadCount.incrementCounter();
*Thread2* ThreadCount.incrementCounter();
*Thread1* ThreadCount.printCounter(this);
*Thread2* ThreadCount.printCounter(this);
In this action Thread 1 increment by 2 and Thread2 increment by 0.
You can use AtomicInteger etc for thread-safe operations.
You should encapsulate int. Don't leave public.
I am looking at https://docs.oracle.com/javase/8/docs/api/java/util/concurrent/package-summary.html#MemoryVisibility and having trouble understanding what this means - "All actions in a thread happen-before any other thread successfully returns from a join on that thread." Can I please get an example on what this means and what is the happen-before guarantee in the example.
If you have he following code
public class Test {
public static int i = 1;
public static void main(String[] args) throws Exception {
System.out.println("Start main");
Thread t = new Thread(new Runnable() {
public void run() {
System.out.println("Start second");
i = 10;
}
});
t.start();
t.join();
System.out.println("After join");
System.out.println(i); //should print 10
}
}
Everything which is done inside run() method happens before main thread gets control back from t.join();. That is why static variable i will have value 10 when printed in main thread.
I have created sample program of java Thread in which i am using stop() method to stop the thread using below program
public class App extends Thread
{
Thread th;
App(String threadName)
{
th = new Thread(threadName);
}
public synchronized void run() // Remove synchronized
{
for (int i = 0; i < 5; i++) {
System.out.println(th.getName()+" "+i);
try {
Thread.sleep(500);
} catch (InterruptedException e) {
}
}
}
public static void main( String[] args )
{
App thread_1 = new App("Thread-1");
thread_1.start();
thread_1.setPriority(MAX_PRIORITY); //Comment this
thread_1.stop();
App thread_2 = new App("Thread-2");
thread_2.start();
}
}
The output of the above program is :
Thread-1 0
Thread-1 1
Thread-1 2
Thread-1 3
Thread-1 4
Thread-2 0
Thread-2 1
Thread-2 2
Thread-2 3
Thread-2 4
i.e. thread_1 is not stopped. When i am removing synchronized or priority in the code thread is stopped immediately and output will be
Thread-2 0
Thread-2 1
Thread-2 2
Thread-2 3
Thread-2 4
I am not able to understand why it is working like this.
Most of the public methods of the Thread class are synchronized on the Thread instance itself. http://hg.openjdk.java.net/jdk6/jdk6/jdk/file/5672a2be515a/src/share/classes/java/lang/Thread.java
Your run() method is synchronized on the Thread instance. The stop() method calls stop(Throwable), which is also synchronized on the Thread instance, its signature is:
#Deprecated
public final synchronized void stop(Throwable obj) {
The synchronization prevents the main thread from entering thread_1.stop() while the thread itself is still running in your synchronized run() method.
This is an example of why it's wise to always use private objects for synchronization. E.g., do this...
class Foobar {
private final Object lock = new Object();
public void do_something() {
synchronized(lock) {
...
}
}
}
Instead of doing this...
class Foobar {
public synchronized void do_something() {
...
}
}
The second version is more verbose (Welcome to Java!), but it prevents the user of your Foobar class from using it as a synchronization object in a way that interferes with its own use of itself as a synchronization object.
Thread.stop() is deprecated. consider using this instead:
public class App extends Thread
{
Thread th;
volatile boolean bStopThread;
App(String threadName)
{
th = new Thread(threadName);
bStopThread = false;
}
public void stopThread(){
bStopThread = true;
}
public synchronized void run() // Remove synchronized
{
for (int i = 0; i < 5; i++) {
if(bStopThread) return;
System.out.println(th.getName()+" "+i);
try {
Thread.sleep(500);
} catch (InterruptedException e) {
}
}
}
public static void main( String[] args ) throws InterruptedException
{
App thread_1 = new App("Thread-1");
thread_1.start();
thread_1.setPriority(MAX_PRIORITY); //Comment this
thread_1.stopThread();
App thread_2 = new App("Thread-2");
thread_2.start();
}
}
It should works as you want, although I haven't tested.
You have 3 threads in your application: main thread, running the code of the main method, thread_1 and thread_2. Your main thread starts thread_1 at some point in time X, then calls thread_1.stop() in some point in time Y, Y>X.
Now, what can happen between points X and Y, is that CPU scheduler can decide: "I will now let thread_1 run". Thread_1 will get CPU, will run and will print his text. OR, CPU scheduler can decide: "main thread is now running... let it run". And thread_1 will not get CPU until stop is called and will print nothing.
So you have uncertainty outside of your control about CPU scheduling. You can only assume that raising the priority of the thread hints scheduler to pick the first of the aforementioned choices.
But. stop is deprecated, so never use that. And don't try to guess the order of the execution of the multiple threads.
Put a try catch in your main method. Print stack trace and message of caught exception. Same in run method. Then java will tell you issue.
MHC's method is better but like I said - sometimes (rarely) when you have no control over the thread, can only call stop. But in this case you do have control over it so MHC method will work nicely.
But I do not see what is the issue with your code - it runs fine in my laptop, maybe you did not clean and re compile? Chane some message so you know latest code is running
I used :
package academic.threads;
public class StopThHighPri extends Thread {
Thread th;
volatile boolean bStopThread;
StopThHighPri(String threadName) {
th = new Thread(threadName);
bStopThread = false;
}
public void stopThread(Thread t) {
//bStopThread = true;
try {
t.stop();
} catch (Throwable e) {
System.err.println(" Stop th " + e + " " + e.getMessage());
}
}
public synchronized void run() // Remove synchronized
{
try {
for (int i = 0; i < 5; i++) {
if (bStopThread)
return;
System.out.println(th.getName() + " " + i);
try {
Thread.sleep(500);
} catch (InterruptedException e) {
}
}
} catch (Exception e) {
e.printStackTrace();
System.out.println("run err " + e);
}
}
public static void main(String[] args) {
try {
System.err.println("Code version 002");
StopThHighPri thread_1 = new StopThHighPri("Thread-1");
thread_1.start();
thread_1.setPriority(MAX_PRIORITY); // Comment this
thread_1.stopThread(thread_1);
StopThHighPri thread_2 = new StopThHighPri("Thread-2");
thread_2.start();
} catch (Exception e) {
e.printStackTrace();
System.out.println("MNain err " + e);
}
}
}
Put something like System.err.println("Code version 002");
and change the 002 , 003. so you know latest code is working every time you edit the class. Again for learning this is okay but do not need to use stop here
I'm on Java concurrency at the moment.
I don't know how to write negative scenario test.
I need a way to make deadlocks and I need a way to see that without using synchronization
I could end up with problems like inconsistency.
What is generally best way to write some stress test code
that could show me bad results if synch is omitted?
Any code example would be really appriciated.
Thank you all in advance!
The following code will almost certainly create a deadlock and demonstrates the classic deadlock scenario whereby two different threads acquire locks in an inconsistent order.
public class Main {
private final Object lockA = new Object();
private final Object lockB = new Object();
public static void main(String[] args) {
new Main();
}
public Main() {
new Thread(new Runnable() {
public void run() {
a();
sleep(3000L); // Add a delay here to increase chance of deadlock.
b();
}
}, "Thread-A").start();
new Thread(new Runnable() {
public void run() {
// Note: Second thread acquires locks in the reverse order of the first!
b();
sleep(3000L); // Add a delay here to increase chance of deadlock.
a();
}
}, "Thread-A").start();
}
private void a() {
log("Trying to acquire lock A.");
synchronized(lockA) {
log("Acquired lock A.");
}
}
private void b() {
log("Trying to acquire lock B.");
synchronized(lockB) {
log("Acquired lock B.");
}
}
private void sleep(long millis) {
try {
Thread.sleep(millis);
} catch(InterruptedException ex) {
}
}
private void log(String msg) {
System.err.println(String.format("Thread: %s, Message: %s",
Thread.currentThread().getName(), msg));
}
}
The following code demonstrates a situation likely to create inconsistent results due to lack of concurrency control between two threads.
public class Main {
// Non-volatile integer "result".
private int i;
public static void main(String[] args) {
new Main();
}
public Main() {
Thread t1 = new Thread(new Runnable() {
public void run() {
countUp();
}
}, "Thread-1");
Thread t2 = new Thread(new Runnable() {
public void run() {
countDown();
}
}, "Thread-2");
t1.start();
t2.start();
// Wait for two threads to complete.
t1.join();
t2.join();
// Print out result. With correct concurrency control we expect the result to
// be 0. A non-zero result indicates incorrect use of concurrency. Also note
// that the result may vary between runs because of this.
System.err.println("i: " + i);
}
private void countUp() {
// Increment instance variable i 1000,000 times. The variable is not marked
// as volatile, nor is it accessed within a synchronized block and hence
// there is no guarantee that the value of i will be reconciled back to main
// memory following the increment.
for (int j=0; j<1000000; ++j) {
++i;
}
}
private void countDown() {
// Decrement instance variable i 1000,000 times. Same consistency problems
// as mentioned above.
for (int j=0; j<1000000; ++j) {
--i;
}
}
}
In above deadlock example. Period for deadlock is 3 second. After which lockA and lockB are released and occupied by Thread 2 and Thread 1