Accessing an object from another thread - java

I've got 2 classes (1 is a basic class, 2nd one extends Thread class) and I'm trying to access an object (class) that is initialized in my thread class on run() using setText()
public class TThread extends Thread{
Patcher pf;
public TThread(String string) {
setName(string);
start();
}
#Override
public void run() {
pf = new Patcher("Checking Serial key..."); //<=== Class initialized here in a separate thread
}
public void setText(String string) {
pf.setText(string); //<=== Trying to access patcher here, throws NullPointerException
}
}
This is how I call TThread
public void myCall(){
TThread tpf = new TThread("pf thread");
//some code later
try{
tpf.setText("blabla");
}
The pf.setText() throws NullPointerException when I'm trying to access patcher from another thread.
How can I get to that thread and access patcher from another class or this class?

This is classic race condition. Because you have two threads, there is no guarantee what will happen first. pf might be accessed by main thread before it's initialized by a background thread.
Right now, your program is unpredictable. Try adding Thread.sleep(100); at the beginning of setText method. It will appear to work correctly, but it might still fail in some specific circumstances.
One way to fix it is to wait in main thread until pf is initialized:
#Override
public synchronized void run() {
pf = new Patcher("Checking Serial key...");
notifyAll();
}
public synchronized void setText(String string) throws InterruptedException {
while(pf==null) {
wait();
}
pf.setText(string);
}
Be careful. If you have not worked with threads before, it might be tricky to get right.

It is a time consuming process to start a new Thread. With a small delay your code will execute successfully:
TThread thread = new TThread("str");
Thread.sleep(1000);
thread.setText("str2");
So the problem is that your thread had no time to execute the run method (and create the instance). You should check the existance of the instance, and wait for it's creation in the setText method - or instantiate it in the TThread's constructor.

Related

Problems with multithread programming in Java [closed]

Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 8 years ago.
Improve this question
I'm studying Java using the book by Gosling. There is a question in the chapter devoted to the multithread programming:
Write a program, which will create a message each second from the beginning of the session. Another thread of this program should create a message each 15 sec. You should provide the possibility of every second-notification by the thread which is counting time.
Here is my solution (it doesn't work and i can't understand why, i think, i just can't properly understand the principle on creating a thread):
public class test {
public static void main (String [] args) throws InterruptedException{
chrono my=new chrono();
my.timer();
Runnable t1=new messenger(5);
Runnable t2=new messenger(1);
new Thread(t1, "t1").start();
new Thread(t2, "t2").start();
}
}
class chrono {
static int time=0;
public synchronized void timer() throws InterruptedException {
Thread.sleep(1000);
time++;
System.out.println(time);
notifyAll();
}
}
class messenger implements Runnable {
int time;
messenger(int time) {
this.time=time;
}
synchronized void timerListener() {
try {
while (chrono.time%time!=0) {
wait();
}
System.out.println("Thread "+this.time);
} catch(InterruptedException e) {}
}
public void run() {
timerListener();
}
}
New version:
public class test {
public static void main (String [] args) throws InterruptedException{
Chronometr my=new Chronometr();
Runnable t1=new Messenger(5, my);
new Thread(t1, "t1").start();
for (int i=0;i<6;i++) {
synchronized(my) {
my.timeCount();
my.notifyAll();
}
}
}
}
class Chronometr {
static int time=0;
public void timeCount() throws InterruptedException {
Thread.sleep(1000);
time++;
System.out.println(time);
}
}
class Messenger implements Runnable{
int time;
public Chronometr ch;
Messenger(int time, Chronometr ch) {
this.time=time;
this.ch=ch;
}
public void waitForTime() {
synchronized (ch) {
try{
while (Chronometr.time%time!=0)
ch.wait();
System.out.println("Thread "+this.time);
}
catch(InterruptedException e) {}
}
}
public void run() {
waitForTime();
}
}
Last change:
public class test {
public static void main (String [] args) throws InterruptedException{
Chronometr my=new Chronometr();
Runnable t1=new Messenger(5, my);
new Thread(t1, "t1").start();
for (int i=0;i<10;i++) {
synchronized(my) {
Chronometr.time+=1;
System.out.println(Chronometr.time);
my.notifyAll();
//my.wait();
}
Thread.sleep(1000);
}
}
}
Edit: Just noticed another big problem: The code calls Thread.sleep() inside a synchronized block. No! No! No! No! No!
When I run the newer version of your program as-is, the Messenger thread usually never gets to run: Here's what I think happens:
main thread messenger thread
----------- ----------------
starts messenger
locks chronometer
sleeps enters waitForTime()
blocks trying to lock
chronometer
---one second later---
wakes up from sleep
increments time
prints message
calls notifyAll()
(Has no effect, 'cause
messenger is not in
wait() call)
ulocks the lock
re-locks the lock wakes up
sleeps blocks trying to lock
chronometer
. .
. .
. .
Try moving the Thread.sleep(1000) call out of the Chronometer.timeCount() method, into the main() method, outside of the synchronized(my) block. I'm guessing that the output will be more like what you expected.
Original answer below the line,
Your biggest problem is this:
chrono.timer() method calls notifyAll() on itself (i.e., on the chrono instance referenced by the "my" variable in main()). Who calls wait() on that object? Nobody is who. Your messanger objects wait() on themselves. Who notifies them? Nobody is who.
Other comments (in no particular order):
(1) Class names should be CamelCase beginning with a capital letter. The more your code looks like everybody else's, the more everybody else will be willing to try to understand it and help you out.
(2) If you have only one variable of type FooBarBaz, then the variable should be named fooBarBaz. Same reason.
(3) Class names should be nouns (e.g., Chronometer instead of the ambiguous chrono), method names should be verbs (e.g., waitForTimerTick() instead of timerListener()). Same reason.
(4) the my.timer(); call in main could not have any possible effect on the threads that you create and start after it returns. A foo.notify() call does nothing if there are no other threads already waiting in foo.wait() when notify() is called.
(4a) A variable named "my" is an abomination.
(5) the my.timer() call waits for one second, increments my.time, notifies nobody, and then it's done. For good. In particular, nobody will ever increment my.time again.
(5a) The problem statement clearly says that the program should go on forever periodically printing out messages, but there are no loops in your program except for the wait() loop in messenger.timerListener().
(6) You might want to get some more experience writing single-threaded programs that solve real problems before you try to tackle threads.

Why Thread.start() is needed? [duplicate]

This question already has answers here:
Please explain the output from Thread run() and start() methods
(4 answers)
Closed 8 years ago.
I was working on Threads when a question struck to my mind..If we can directly call run() method with the object of a class like any ordinary method then why do we need to call Thread.start() to call run() method..I tried both the methods as shown and got same result with both of them
First attempt by calling run() method directly
class Abc extends Thread
{
public void run()
{
for(int i=0;i<5;i++)
{
System.out.println("Abc");
}
try
{
Thread.sleep(100);
}catch(Exception e)
{
System.out.println("Error : "+ e);
}
}
}
class Xyz extends Thread
{
public void run()
{
try
{
for(int i=0;i<5;i++)
{
System.out.println("Xyz");
}
Thread.sleep(100);
}catch(Exception e)
{
System.out.println("Error : "+ e);
}
}
}
public class ThreadDemo
{
public static void main(String[] args)
{
Abc ob=new Abc();
Xyz oc=new Xyz();
ob.run();
oc.run();
}
}
Second attempt by calling Thread.start()
public class ThreadDemo
{
public static void main(String[] args)
{
Abc ob=new Abc();
Xyz oc=new Xyz();
Thread t1,t2;
t1=new Thread(ob);
t2=new Thread(oc);
t1.start();
t2.start();
}
}
If you call run() directly, the code gets executed in the calling thread. By calling start(), a new Thread is created and executed in parallel.
If you directly call run(), then all the work will be done on the main thread.
By using Thread.start, then it will executed on a new thread other than the main thread ;)
To observe what the difference is, increase your sleep calls to something longer like 10 seconds. This will make it obvious that you need Thread.start to avoid the first task waiting on the second.
In the case where you use Thread.start, you will see that output of both threads appears immediately.
In the case where you use run, you will see that the output of the first appears, then a 10 second delay, then the output of the second.
If you call run() method directly then code will run inline. To run the code in separate thread it is necessary to call Thread.start().
When you call start() method on thread reference it create span entirely context area. Then thread will have independent stack from where you are calling. More over start() invokes OS native thread to start it in separate memory context.
While run() method invocation considered as simple method call, and you won't have benefit of concurrency as its executing is current stack.

Calling functions from threads

I am beginner in java. I have been studying multithreading. I want to create two threads and these two threads must run separate methods concurrently. Here these threads should call sum and diff method and run simultaneously. But I am getting an error, that method should be of thread type. How to achieve it.
class Demo implements Runnable
{
void sum()
{
//Some lines of code
}
void diff()
{
//Some lines of code
}
public void run ()
{
System.out.println("Inside run");
}
}
class Test
{
public static void main (String []args){
Demo o = new Demo ();
Demo o1 = new Demo ();
Thread th = new Thread (o);
Thread th1= new Thread(o1);
th.start();
th1.start();
o.th.sum(); // getting error here
o1.th1.diff(); // getting error here
}
}
First of all you have a compilation error because you're trying to reference the variable th as a field on an object of type Demo. th is not a field, but rather a local variable and can be referenced directly (i.e. without the o. prefix). Second, sum() and diff() cannot be called against an instance of Thread as those methods are not defined by thread, but rather by your own Demo class.
All that being said, these compilation problems aren't even the root issue for this code. Based on your code it seems you have some fundamental misunderstandings about the syntax and structure of Java programs so it might benefit you to go through some entry-level tutorials before trying to tackle concurrent programming. But, for the sake of completeness here is a brief explanation of what you need to do in order to make your program work.
When you call Thread.start() it's going to fork a thread and call the run() method of the Runnable you passed into that thread object's constructor.
In order to call the two different methods you need to create two different classes that implement runnable and put the two method implementations in each of their run methods.
Example:
public class Sum implements Runnable {
public void run() {
//Add up your numbers
}
}
public class Diff implements Runnable {
public void run() {
//Subtract numbers
}
}
public class Test {
public static void main(String[] args) {
Thread sumThread = new Thread(new Sum());
Thread diffThread = new Thread(new Diff());
sumThread.start();
diffThread.start();
}
}
Assuming that you are getting a compilation error, the statement o.th.sum() is incorrect.
The statement o.th will cause the compiler to look for a public static class level field in the Demo class with the name th. Since there is no such field in Demo class, you get an error.
You are getting this error because you are trying to access the Thread's local variable using the object of the Demo class and you can't call the method directly if you want's it to run it in a separate thread. A new thread will spawn only when you call start() method on thread class and then it will execute the code in run() method.
As per your requirement to create two threads and these two threads must run separate methods concurrently, following code should work.
class Demo implements Runnable
{
public void run ()
{
//sum() method code
}
}
class Demo1 implements Runnable
{
public void run ()
{
//diff() method code
}
}
class Test
{
public static void main (String []args){
Demo o = new Demo ();
Demo1 o1 = new Demo1 ();
Thread th = new Thread (o);
Thread th1= new Thread(o1);
th.start();
th1.start();
}
}

Controlling the execution of a method via Threads in Java

I need to have two classes, one class has two methods each of which will take a while to execute completely. The second class is given information which will decide which one of the two methods in the first class will execute. It is important however that if the second class (which will be executing at the same time in its own thread) decides that the other of the two methods should execute, the first class would go straight to executing the other method and not have to wait for the first to finish.
If class A has the two methods and class B is in parallel in a different thread deciding which method to execute then here is an example:
A is executing method 1 which will take a while to return. During the execution of method 1, class B decides method 2 should execute which means class A should immediately stop doing method 1 and go on to execute method 2.
Is this possible? Maybe with interrupts?
thanks
If you make Class A implement runnable and then execute its method by having Class B create a new Thread with an object of type Class A, you can have Class B call the interrupt method on the Class A thread.
Here's an outline of something that should work:
class ClassA implements Runnable {
public volatile boolean switchToOther;
#Override
public void run() {
switchToOther = false;
try {
method1();
} catch (InterruptedException e) {
// Restore the interrupted status
Thread.currentThread().interrupt();
}
if (switchToOther) {
method2();
}
}
public void method1() throws InterruptedException {
work();
}
public void method2() throws InterruptedException {
otherWork();
}
}
class ClassB implements Runnable {
#Override
public void run() {
ClassA a = new ClassA();
Thread t = new Thread(a);
t.start();
if (decideToSwitch()) {
a.switchToOther = true;
t.interrupt();
}
}
}
Note:
InterruptedException can happen beyond your control, so you should check it's due to an explicit switch,
the volatile on the switchToOther field used from several threads,
the resetting of the interrupted state, which is standard idiom when catching InterruptedException

how to override thread.start() method in java?

I need to implement thread.start() method in my java code. Please let me know through an example of overriding of thread.start() method and how it works?
You should not. Override run instead
You can override start as any other method
Thread myThread = new Thread() {
#Override
public void start() {
// do something in the actual (old) thread
super.start();
}
#Override
public void run() {
// do something in a new thread if 'called' by super.start()
}
};
but you must call super.start() to create a new thread and have run() called in that new thread. The original start does some magic (native code) that you hardly can mimic.
If you call run() directly from within your start() (or any other method), it is executed in the actual thread as a normal method, not in a new thread. There is no reason to use a Thread if you don't want to run some code in a new thread.
You must put your decision logic in the run() method, maybe using some variable set in the constructor (or another method, eventually in start) if that is really needed. I can not find any reason for needing this variable, it should be enough to test the condition in run() as already suggested elsewhere.
class MyThread extends Thread {
private final boolean flag;
public MyThread(boolean someCondition) {
flag = someCondition;
}
// alternative
// #Override
// public synchronized void start() {
// flag = <<someCondition>>
// super.start();
// }
#Override
public void run() {
if (flag) {
// do something like super.run()
} else {
// do something else
}
}
}
but it would be easier to understand and maintain if you do it like #Henning suggested!
It's also a more object oriented solution...
As others said, overriding Thread.start() is not the way to do it. Usually, I wouldn't override Thread.run() either, but use a Runnable.
If you have to decide which method to run after the thread has been spawned, you could do something like this:
final Runnable runnableA = ...;
final Runnable runnableB = ...;
Runnable r = new Runnable() {
#Override
public void run() {
if (...) {
runnableA.run();
} else {
runnableB.run();
}
}
}
Thread thread = new Thread(r);
thread.start();
If, as you say, you have a superclass and a subclass where the run() method is overidden, you can just rely on late binding and the proper method will be invoked automatically:
Runnable couldBeAOrB = ...;
Thread thread = new Thread(couldBeAOrB);
thread.start();
You don't override the start, you override the "run". You can simply implement a thread by:
new Thread() {
public void run() {
//your code here
}
}.start();
//start will call the logic in your run method
Actually, you can call run() to run a thread instead of start() to run a thread. But there is a little difference.
Suppose you create two threads:
Thread t1 = new Thread();
Thread t2 = new Thread();
Case 1 : If you call "t1.run()" and "t2.run()" one after another they will start to run t1 and t2 synchronously (sequentially).
Case 2 : If you call "t1.start()" and "t2.start()" one after another they will call their run() methods and start to run t1 and t2 asynchronously (in parallel).
Agree with Schildmeijer, don't override start, override run() instead.
In fact, although start can be overridden (it's not final), it calls the native start0 method which in turn will cause the VM to call the run method (actually from the context of a native thread/process). The native start0 method has private access, so even if you overrode the start, I can't see how you could reproduce the affect.
The client calling start() is within a thread (lets say, the main thread), it's not until the run method has done its thing that another thread will be spawned.
Take a look at the Sun (ahem, Oracle) tutorial on threads at http://download.oracle.com/javase/tutorial/essential/concurrency/index.html, in particular the section on starting threads.
class Worker implements Runnable{
public void run(){
if("foo"){
runFoo();
} else {
runBar();
} }
private void runFoo(){
// something }
private void runBar(){
// else }
}
I'm pretty sure, you needn't to overwrite the start-Method.
By the way: Take al look at java.util.concurrent.Callable
http://download.oracle.com/javase/1.5.0/docs/api/java/util/concurrent/Callable.html
It is discouraged to override Thread, if possible create an implementation of the Runnable interface instead and run that on a thread. This can also be done with a lambda expression, making everythin super short and simple.
// create a new thread and give it a Runnable with a lambda expression and a custom name
Thread thread = new Thread(() -> {
// put your code here
}, "CustomThreadName");
// start it
thread.start();
If we provide our own implementation of start method then it will work like a normal method call and will work on the current thread stack only. New thread will not be created.
Yes the start() method can be overridden. But it should not be overridden as it is implementation in thread class has the code to create a new executable thread and is specialised.
We can override start/run method of Thread class because it is not final. But it is not recommended to override start() method
class Bishal extends Thread {
public void start()
{
System.out.println("Start Method");
}
public void run()
{
System.out.println("Run Method");
}
} class Main{
public static void main(String[] args)
{
Bishal thread = new Bishal();
thread.start();
System.out.println("Main Method");
}
}
when we are calling start() method by an object of Bishal class, then any thread won’t be created and all the functions are done by main thread only.

Categories