Starting Threads In A Constructor - java

It is said threads should NEVER be started in constructors, but I am not sure how this reference escapes the Test constructor in this case. I looked at the underlying Thread.java and I cannot figure this out.
class Test {
static MyThread thread;
public Test() {
thread = new MyThread();
thread.start();
}
}
class MyThread extends Thread {
public void run() {
//do stuff
}
}
Thanks for the help.
thread = new MyThread(); would call Thread super constructor:
public Thread() {
init(null, null, "Thread-" + nextThreadNum(), 0);
}
I do not see a reference getting away.

this can only escape if the thread references this (eg, if it's an inner class)
Your thread does not reference this, so this is not an issue.
However, constructing an object is generally expected to be side-effect-free; this is not a good idea.

Related

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.

When we call thread.start() which thread is invoked first

Here my code is:
public class Child extends Thread {
public void run(){
synchronized (this)
{
for(int i=1;i<=5;i++)
{
System.out.println("child thread");
}
}
}
}
class ThreadTest{
public static void main(String []a) {
Child child=new Child();
**child.start();**
synchronized (child)
{
for(int i=1;i<=5;i++)
{
System.out.println("parent thread");
}
}
}
}
It first prints "parent thread" after that it prints "child thread" but my doubt is, when we invoke start() method there is a chance to invoke child thread before main thread. But it always prints "parent thread" after that "child thread". can any one explain?
Somewhere inside the child.start() call (i.e., before start() returns) the new thread is created, and it becomes eligible to run. From that point on, it's a race to see which thread will reach it's respective synchronized(...) block first. There's no way to know which one will win, and there's no reason to think that it will be the same winner every time.
P.S.: Synchronizing on a Thread object is not a good idea. The Thread class also synchronizes on Thread instances for its own purposes, and there is a risk that your use of the Thread object as a lock could interfere with the Thread class's use of it.
A good habit is to synchronize on a private object.
class MyClass {
private final Object myLock = new Object();
SomeType someMethod(...) {
synchronized(myLock) {
....
}
}
}

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.

How to access a method from another running thread in java

I am new to Java Threads. What I am trying to do is from ThreadB object gain access to the instance of a current running thread, ThreadA, and call its method called setSomething.
1) I think I am making harder than it really is
2) I have a null pointer exception so I must be doing something wrong when accessing that method
Here is what I have so far and I have done my due diligence and looked here on StackOverflow for a similar question.
I have a current Thread running in the background:
// assume this thread is called by some other application
public class ThreadA implements Runnable{
private Thread aThread;
public ThreadA(){
aThread = new Thread(this);
aThread.setName("AThread");
aThread.start();
}
#Override
public void run(){
while(true){
// doing something
}
}
public void setSomething(String status){
// process something
}
}
// assume this thread is started by another application
public class ThreadB implements Runnable{
#Override
public void run(){
passAValue("New");
}
public void passAValue(String status){
// What I am trying to do is to get the instance of ThreadA and call
// its method setSomething but I am probably making it harder on myself
// not fully understanding threads
Method[] methods = null;
// get all current running threads and find the thread i want
Set<Thread> threadSet = Thread.getAllStackTraces().keySet();
for(Thread t : threadSet){
if(t.getName().equals("AThread")){
methods = t.getClass().getMethods();
}
}
//**How do I access ThreadA's method, setSomething**
}
}
Thank you in advance
Allen
Wow why do you make things to much complex?! this is not as hard as you think (killing a dragon in a dark castle!)
okay all you need to do is passing the threadA references to threadB! just this. and let me say that when you call a method from thread b, so it runs by thread b, not the class has been hosted.
class ThreadA implements Runnable {
public void run() {
//do something
}
public void setSomething() { }
}
class ThreadB implements Runnable {
private ThreadA aref;
public ThreadB(ThreadA ref) { aref = ref; }
public void run() {
aref.setSomething(); // Calling setSomething() with this thread! (not thread a)
}
}
class Foo {
public static void main(String...arg) {
ThreadA a = new ThreadA();
new Thread(a).start();
ThreadB b = new ThreadB(a);
new Thread(b).start();
}
}
and here a simple threadtutorial
When or after you instantiate your ThreadB object, give it a reference to your ThreadA object instance. Something like:
ThreadA a = new ThreadA();
ThreadB b = new ThreadB(a);
Then, within the ThreadB code, you can just invoke ThreadA's method by using the reference you have no doubt stored in an instance variable in ThreadB.

How locks obtained in multithreading and on which object?

Class ThreadTest extends Thread {
public synchronized void run() {
}
public static void main(String args[])
{
Thread t1=new ThreadTest();
Thread t2=new ThreadTest();
t1.start();
t2.start();
}
}
I want to know in above scenario, how locks obtained and on which object?
Does above scenario valid?
As locks are obtained on a calling object in method synchronisation then in above scenario on which object lock will be obtained. One more question who(or which object) invokes the run method?
Thanks,
-Abhishek
t1 has the lock of the t1 instance.
t2 has the lock of the t2 instance.
But your example doesnt make much sense..
Maybe this example will help you:
public class Test extends Thread {
private String name;
public Test(String name) {
this.name = name;
}
public synchronized void run() {
System.out.println(name);
while(true)
{
// loop endless
}
}
public static void main(String args[])
{
Thread t1= new Test("t1");
Thread t2= new Test("t2");
t1.start();
t2.start();
}
}
The output is:
t1
t2
You have started both the threads, but it depends on JVM which thread it might execute, so depending upon the thread which starts executing will acquire the lock first and the second thread cant be on running state till the first thread stops.
but in your case as both are different thread instances they run parallel, as the lock is acquired at the object level.
Your example doesn't make that much sense, because locks are on a per-instance level, not on a per-class level as you might wanted to use them.
I think you got it wrong a bit. The thread is wrapping up the code that is executing commands. These executions often contain access on other objects. That is the point, where locking comes into the game. Each of these objects have a monitor that can be obtained by threads. However, only one thread can obtain the lock at a time. Thus, other threads are enqueued and can access object as soon as the current holder releases it, trivially by exiting a synchronized code block.
I think you might wanted to do something like this:
class ThreadTest extends Thread
{
private final Foo f;
public ThreadTest(Foo f,int i)
{
super(""+i);
this.f = f;
}
#Override
public void run()
{
f.bar();
}
public static void main(String args[])
{
Foo f = new Foo();
Thread t1 = new ThreadTest(f,1);
Thread t2 = new ThreadTest(f,2);
t1.start();
t2.start();
}
public static class Foo
{
public synchronized void bar()
{
System.out.print("hello form Thread ");
System.out.println(Thread.currentThread().getName());
}
}
}
Formal Definition
When a thread invokes a synchronized method, it automatically acquires the intrinsic lock for that method's object and releases it when the method returns. The lock release occurs even if the return was caused by an uncaught exception.
If what you want is to have only one thread execute at a time (What's the point) then you should call a static method and call that from inside your run(), there is only one static method for all object of a class
How do synchronized static methods work in Java?

Categories