Strange behaviour in Java concurrency using no synchronization - java

In Java Concurrency in Practice there is a sample that made me confused:
public class Novisibility {
private static boolean ready;
private static int number;
private static class ReaderThread implements Runnable {
public void run() {
while (!ready) {
Thread.yield();
}
System.out.println(number);
}
}
public static void main(String[] args) {
System.out.println("0");
new Thread(new ReaderThread()).run();
System.out.println("1");
number = 42;
System.out.println("2");
ready = true;
System.out.println("3");
}
}
I can understand reordering makes the loop to never break, but I can't understand why "1", "2" and "3" are never printed to console. Could any body help?

You don't spawn a new thread but run it in the current one. Use the start() method instead.
Since you run() executes on the main thread and that method runs in an endless loop you'll never reach the System.out.println() statements (and neither do you reach ready = true;).
From the JavaDoc on run():
If this thread was constructed using a separate Runnable run object, then that Runnable object's run method is called; otherwise, this method does nothing and returns.
And start():
Causes this thread to begin execution; the Java Virtual Machine calls the run method of this thread.

Related

visibility not appear in my java code

I m reading the "java concurrency in practice". When I read the code:
public class NoVisibility
{
private static boolean ready;
private static int number;
private static class ReaderThread extends Thread
{
#Override
public void run()
{
System.out.println(ready+"\t"+number);
while (!ready)
{
Thread.yield();
}
System.out.println(number);
}
}
public static void main(String[]args) throws InterruptedException
{
new ReaderThread( ).start();
Thread.sleep(4000);
number = 42;
ready =true;
}
}
in the book, it says the loop will endless,but when i run it in java8,the result as this:
false 0
42
why does it not show visibility problem?
The thread that is initialized with the lambda expression will start looping immediately. You could see that by putting a print statement into that first while loop.
Then, about 1 second later, the other thread that created that first thread changes the value of ready. As soon as this change becomes effective, that first while loop with !ready will stop.
You either made a mistake when creating your example, or that book is wrong. In other words: ready is visible two both threads; there is nothing in this code which would explain your expectations.

run() is never called by Thread.start() method

I have written a small multithreading program.
public class NewThread implements Runnable {
Thread t;
public NewThread() {
t = new Thread(this, "Thread created by Thread Class.");
System.out.println("Created by constuctor:"+ t);
t.start(); // This will call run, because t has context as this
}
#Override
public void run() {
System.out.println("run() method called.");
}
public static void main(String[] args) {
new NewThread();
}
}
This is how the book says to write it. However, I never get the run() method called statement in the console. Thus, it seems run() is never called. How can this be true?
Edit: Yes, it is bad practice to start a Thread from constructor, but that is not affecting the question. (I am getting so many down votes for that)
run() is never called by Thread.start() method
You code actually works on my system but that it doesn't work on your's, demonstrates that you have a classic race condition.
Inside of main(), the NewThread is constructed but the Java language says that it can reorder operations so that the operations in a constructor can happen after the constructor finishes. So it is possible that main() might finish before the NewThread has actually been started which can result in the JVM shutting down without running the thread.
Because of instruction reordering, you should never have a thread auto-start itself inside of the constructor. See: Why not to start a thread in the constructor? How to terminate?
You should instead do:
public NewThread() {
t = new Thread(this, "Thread created by Thread Class.");
System.out.println("Created by constuctor:" + t);
// don't start here
}
public void start() {
// start in another method
t.start();
}
public void run() {
System.out.println("run() method called.");
}
...
public static void main(String[] args) {
NewThread nt = new NewThread();
nt.start();
}
Since the NewThread has the same daemon status as your main thread (which is non-daemon) the JVM will not shutdown until nt.run() completes.

Calling the run method in a thread

Here I have created the class Main and inside it a thread t1 had been start by sending it a runnable target. But since the thread has been started I believe the run() method, should run and call a.SetI(20) method. But the output gives as 0. Could somone please let me know the logic behind this.
public class _216 {
private int i;
public synchronized void setI(int i){
this.i=i;
}
public synchronized int getI(){
return i;
}
}
class Main{
public static void main(String[] args) {
final _216 a=new _216();
Runnable r=new Runnable(){
#Override
public void run() {
a.setI(20);
}
};
Thread t1=new Thread(r);
t1.start();
System.out.println(a.getI());
}
}
The 'logic behind this' is that the thread may not have executed yet when you do your print.
You should use t1.join() so that both main and this new thread will joined and later code will continue to print.
Here
Thread t1=new Thread(r);
t1.start();
t1.join()
System.out.println(a.getI());
You very well may be printing the result before the thread completes running.
At that point in time the threads may be running simultaneously.
Also recognize that i is never initialized until you call setI, consider hardcoding a default value.

Thread Executor - beginner

I have two classes. In class A, I have the run() method looped forever, while in the class B, i have the threadpool.
My question is, From Class B, how can I control and stop the thread executing run() method in class A , I have tried forceshutdown, threadExecutor.shutdownNow(), But it isnt working.
The loop seems to go on forever.
Here is example piece of code:
public class A implements Runnable {
public void run() {
while (true) {
System.out.println("Hi");
}
}
}
public class B {
public static void main(String[] args) {
int noOfThreads = 1;
A ThreadTaskOne = new A();
System.out.println("Threads are being started from Class B");
ExecutorService threadExecutor = Executors.newFixedThreadPool(noOfThreads);
threadExecutor.execute(ThreadTaskOne);
threadExecutor.shutdownNow();
System.out.println("B Ends, no of threads that are alive : " + Thread.activeCount());
}
}
As #MadProgammer said, your "infinite" loop needs to pay attention to Thread.isInterrupted. e.g. (very schematic)
public void run() {
while (!Thread.isInterrupted()) {
doSomethinginTheLoop1();
blah...blah...blah
// if the loop is very long you might want to check isInterrupted
// multiple times for quicker termination response
doSomethingInTheLoop2();
}
// now, here's a decision of what you do
// do you throw an InterruptedException or trust others to check interrupted flag.
// read Java COncurrency in Practice or similar...
}
The documentation on ExecutorService#shutdownNow() says -
There are no guarantees beyond best-effort attempts to stop processing actively executing tasks. For example, typical implementations will cancel via Thread.interrupt(), so any task that fails to respond to interrupts may never terminate.
And your thread doesn't seem to care if it has been interrupted.
So check if it has been interrupted
while (Thread.currentThread().isInterrupted())
instead of just doing
while (true)
May be below is useful for you.
public static class A implements Runnable {
public void run() {
while (!Thread.currentThread().isInterrupted()) {
System.out.println("Hi");
}
}
}

Stopping Thread in Java

if i have got such java code:
public static void main(String[] args)
{
for(int i = 0;i<100;i++)
{
Future<?> f = ThreadPoolManager.getInstance().schedule(new START(), 500);
f.cancel(true);
}
}
private class START implements Runnable
{
#Override
public void run()
{
System.out.println(1);
}
}
And run it in debug, i can see that all of those threads(after cancel) are still running, so are they taking my memory too? And if yes, how can i destroy those Threads completely?
cancel(true) calls interrupt() on your thread, nothing more. So, you need to handle it properly in your run() method. For your simple case your threads will finish their execution and their objects will be cleared by GC.

Categories