Thread field inside a class that implements Runnable, which instantiates said class - java

In my school's program solutions for multithreading problems and exercises, classes that implement the Runnable interface are usually given a Thread field, which is automatically instantiated in the following example:
protected Thread thr = new Thread(this);
This field is subsequently used as a means of controlling the Thread over which the class itself is instantiated. For example:
public void stop() {
if (thr != null) thr.interrupt();
}
Which is then used to interrupt Thread objects made with the Runnable class.
A full class example, ported directly from an aforementioned solution, is given below:
package hokej;
import java.awt.Color;
public abstract class AktFigura extends Figura implements Runnable {
protected Thread nit = new Thread(this);
private int tAzur;
private boolean radi;
public AktFigura(Scena s, int xx, int yy,
Color b, int t) {
super(s, xx, yy, b); tAzur = t;
}
protected abstract void azurirajPolozaj();
public void run() {
try {
while (!Thread.interrupted()) {
synchronized (this) {
if (!radi) wait();
}
azurirajPolozaj();
scena.repaint();
Thread.sleep(tAzur);
}
} catch (InterruptedException ie) {}
}
public synchronized void kreni() {
radi = true; notify();
}
public void stani() { radi = false; }
public void prekini() {
if (nit != null) nit.interrupt();
}
}
My question is this: How does this work?
Shouldn't the Thread field be a separate object from the object made by calling new Thread(class); in other parts of the program (hence the keyword's name - new)?
Or is this simply a special case that the Java interpreter recognizes in a certain way?
Another question would be the viability of this design as a control method. Is there any simpler/more efficient alternative for controlling a Runnable's thread?

How does this work?
The Thread constructor takes a Runnable, Thread implements this interface. this refers to a Thread instance. So, the statement Thread thr = new Thread(this) is valid, but this practice should be avoided.
Is there any simpler/more efficient alternative for controlling a Runnable's thread?
Thread thread = new Thread(new AktFiguraImpl());
thread.start();
You could control a thread by a class specifically designed for that purpose.
class ThreadController {
public ThreadController(Thread thread, AktFigura figura) { ... }
// methods to manipulate the thread
}

Related

Deadlock when calling two synchronized method

class Downloader extends Thread {
private InputStream in;
private OutputStream out;
private ArrayList<ProgressListener> listeners;
public Downloader(URL url, String outputFilename) throws IOException {
in = url.openConnection().getInputStream();
out = new FileOutputStream(outputFilename);
listeners = new ArrayList<ProgressListener>();
}
public synchronized void addListener(ProgressListener listener) {
listeners.add(listener);
}
public synchronized void removeListener(ProgressListener listener) {
listeners.remove(listener);
}
private synchronized void updateProgress(int n) {
for (ProgressListener listener: listeners)
listener.onProgress(n);
}
public void run() {
int n = 0, total = 0;
byte[] buffer = new byte[1024];
try {
while((n = in.read(buffer)) != -1) {
out.write(buffer, 0, n);
total += n;
updateProgress(total);
}
out.flush();
} catch (IOException e) { }
}
}
The above code is from the book "seven concurrency models in seven weeks". The book says the above code is having potential for the deadlock as the the synchronized method updateProgress calls a alien method[onProgress] that might acquire another lock.
Since we acquire two locks without right order, the deadlock might occur.
Can anyone explain how the deadlock happens in the above scenario?
Thanks in advance.
It's best to make the objects you use with synchronized private.
Since you synchronize on the Downloader, you don't know whether other threads synchronize on the Downloader too.
The following listener causes a deadlock:
MyProgressListener extends ProgressListener {
public Downloader downloader;
public void onProgress(int n) {
Thread t = new Thread() {
#Override
public void run() {
synchronized(downloader) {
// do something ...
}
}
};
t.start();
t.join();
}
}
Code that deadlocks:
Downloader d = new Downloader(...);
MyProgressListener l = new MyProgressListener();
l.downloader = d;
d.addListener(l);
d.run();
The following will happen if you run that code:
the main thread reaches the updateProgress and aquires a lock on the Downloader
the MyProgressListener's onProgress method is called and the new thread t is started
the main thread reaches t.join();
In this situation the main thread cannot procede until t is finished, but for t to finish, the main thread would have to release it's lock on the Downloader, but that won't happen since the main thread can't procede -> Deadlock
First off, recall that the keyword synchronized, when applied to a a class, implies locking the whole object this method belongs to. Now, let's sketch out another couple of objects triggering the deadlock:
class DLlistener implements ProgressListener {
private Downloader d;
public DLlistener(Downloader d){
this.d = d;
// here we innocently register ourself to the downloader: this method is synchronized
d.addListener(this);
}
public void onProgress(int n){
// this method is invoked from a synchronized call in Downloader
// all we have to do to create a dead lock is to call another synchronized method of that same object from a different thread *while holding the lock*
DLthread thread = new DLThread(d);
thread.start();
thread.join();
}
}
// this is the other thread which will produce the deadlock
class DLThread extends Thread {
Downloader locked;
DLThread(Downloader d){
locked = d;
}
public void run(){
// here we create a new listener, which will register itself and generate the dead lock
DLlistener listener(locked);
// ...
}
}
One way to avoid the dead lock is to postpone the work done in addListener by having internal queues of listeners waiting to be added/removed, and have Downloader taking care of those by itself periodically. This ultimately depends on Downloader.run inner working of course.
Probably the problem in this code:
for (ProgressListener listener: listeners)
listener.onProgress(n);
When one thread, which holds a lock, calls an external method
like this one (onProgress) then you cannot guarantee that
implementation of this method won't try to obtain other lock,
which could be held by different thread. This may cause a deadlock.
Here's a classic example that shows the kind of hard-to-debug problems the author is trying to avoid.
The class UseDownloader is created and downloadSomething is called.
As the download progresses, the onProgress method is called. Since this is called from within the synchronized block, the Downloader motinor is locked. Inside our onProgress method, we need to lock our own resource, in this case lock. So when we are trying to synchronize on lock we are holding the Downloader monitor.
If another thread has decided that the download should be canceled, it will call setCanceled. This first tests done so it synchronized on the lock monitor and then calls removeListener. But removeListener requires the Downloader lock.
This kind of deadlock can be hard to find because it doesn't happen very often.
public static final int END_DOWNLOAD = 100;
class UseDownloader implements ProgressListener {
Downloader d;
Object lock = new Object();
boolean done = false;
public UseDownloader(Downloader d) {
this.d = d;
}
public void onProgress(int n) {
synchronized(lock) {
if (!done) {
// show some progress
}
}
}
public void downloadSomething() {
d.addListener(this);
d.start();
}
public boolean setCanceled() {
synchronized(lock) {
if (!done) {
done = true;
d.removeListener(this);
}
}
}
}
The following example leads to a deadlock because the MyProgressListener tries to acquire the Downloader lock while it's already acquired.
class MyProgressListener extends ProgressListener {
private Downloader myDownloader;
public MyProgressListener(Downloader downloader) {
myDownloader = downloader;
}
public void onProgress(int n) {
// starts and waits for a thread that accesses myDownloader
}
}
Downloader downloader = new Downloader(...);
downloader.addListener(new MyListener(downloader));
downloader.run();

Stop the running thread [duplicate]

This question already has answers here:
How interrupt/stop a thread in Java?
(8 answers)
Closed 8 years ago.
public class Threadsample implements ActionListener {
HelloRunner hr = new HelloRunner();
Thread tr1 = new Thread(hr, "ThreadOne");
public void actionPerformed(ActionEvent ae)
{
Object source = ae.getSource();
if (source == b2){
hr.stopRunning();
}
if (source== b1){
tr1.start();
}
}
public class HelloRunner implements Runnable
{
private volatile boolean timeToQuit=false;
int i = 0;
public void run(){
while ( ! timeToQuit ){
System.Out.Println(i);
i++
}
}
public void stopRunning() {
timeToQuit=true;
}
}
}
How do I stop the running thread?
Thread interruption is the way to go:
// computingThread computing here
while (!Thread.currentThread.isInterrupted()){
System.Out.Println(i);
i++;
}
//.... in other part of your program, your main thread for instance:
public void stopComptuterThread() {
computingThread.interrupt(); // assuming computingThread reference reachable
}
Indeed, some people would use Thread.stop() method.. => here's why it would be very bad: https://www.securecoding.cert.org/confluence/display/java/THI05-J.+Do+not+use+Thread.stop()+to+terminate+threads
Thread.stop is deprecated and should not be used.
Sample code is here:
pause-and-resume-thread
Your code will do. You can use build-in interrupt method, which does mostly the same, but also awakes thread with InterruptedException, if it sleeps/waits. It's good to know, that Java doesn't allow to stop threads "the hard way" (except for using .stop() method on thread, which is deprecated).
So process, in general, looks as following:
user requests thread to stop, either by setting a flag (your case) or by invoking .interrupt() method, which sets the flag .interrupted() and "shakes" the thread so it awakes if was sleeping/waiting.
it's thread resonsibility to stop it's execution. If you don't implement some logic handling interruption flag, thread could not react to external thread trying to interrupt it and will die after JVM ends it's execution.
Are you sure, that it's thread issue? Have you checked, if .actionPerformed actually calls .stopRunning method?
Anyway, try following code sample. It works for 100%.
class HelloRunner implements Runnable {
private volatile boolean timeToQuit = false;
int i = 0;
public void run() {
while (!timeToQuit) {
System.out.println(i);
i++;
}
}
public void stopRunning() {
timeToQuit = true;
}
}
public class MainRunner {
public static void main(String[] args) throws InterruptedException {
HelloRunner hr = new HelloRunner();
Thread tr1 = new Thread(hr, "ThreadOne");
tr1.start();
Thread.sleep(100);
hr.stopRunning();
}
}

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.

can i know the Thread runnable class attributes in java?

probability this question have been asked before but i cant find anything in my searching mechanism. I am trying to create a multiple threads, in an array list but i want to retrieve them from an arraylist and filter them by the attribute of w1 i used in my code. any ideas ?
w1 = new FirstWorker(ProductsList, OrdersList, s);
FirstWorkerThread = new Thread(w1);
ThreadArrayList.add(FirstWorkerThread);
//I know i cant do the code below but i want to do that how ?
for(Thread x : ThreadArrayList){
x.ProductsList
}
this is FirstWorker class
import java.lang.String;
import java.util.HashMap;
/*
* To change this template, choose Tools | Templates and open the template in
* the editor.
*/
/**
*
* #author Dimitris
*/
public class FirstWorker extends Thread implements Runnable {
private OrderList orderlist;
private ProductList productlist;
private String Worker;
boolean Stop;
private int speed = 1000;
public FirstWorker(ProductList productlist, OrderList orderlist, String Worker) {
this.productlist = productlist;
this.orderlist = orderlist;
this.Worker = Worker;
this.Stop = true;
}
public void run() {
if (Stop == true) {
try {
Thread.sleep(100);
} catch (InterruptedException e) {
}
while (orderlist.returnLengthofOrder() != 0) {
if (Thread.interrupted()) {
System.out.println("I am in the thread inturrupt");
// We've been interrupted: no more crunching.
return;
}
if (orderlist.getDone() == true) {
} else if (orderlist.getDone() == false) {
orderlist.setDoneTrue();
orderlist.Purchased(Worker);
orderlist.setDoneFalse();
try {
Thread.sleep(this.speed);
} catch (InterruptedException e) {
return;
}
}
}
}
}
public void setWork() {
Stop = false;
}
public void setSpeed(int speed) {
this.speed = speed;
}
}
If you want to access a member variable of your Runnable, you should extend Thread instead of implementing Runnable. Also, don't extend Thread AND implement Runnable. Pick one.
public class MyThread extends Thread
{
public int myarg;
public void run()
{
}
}
public void useThread(int inputArgs[])
{
ArrayList<MyThread> threadArray = new ArrayList<MyThread>();
for (int arg : inputArgs)
{
MyThread temp = new MyThread(arg);
temp.start();
threadArray.add(temp);
}
for (MyThread t : threadArray)
System.out.println(t.myarg);
}
The simple answer with constructing a Thread with a Runnable is no.
The constructor for Thread that you are using accepts a Runnable ... I assume that FirstWorker implements the Runnable interface.
But looking at the API docs for Thread http://docs.oracle.com/javase/6/docs/api/java/lang/Thread.html there is no method to return the Runnable.
Without knowing more context about what your trying to do, the simplest approach might be to change FirstWorker to extend Thread then the loop you have would work.
That would probably work, but would need to know more about what your doing to reccomend anything else.
If you want to retrieve properties from the Runnable instance within a Thread object, I do not believe that is generally possible, since the Thread class does not have a method to return its target Runnable object.
That said, you can always extend the Thread class itself, which would allow you to use instanceof with the Thread instances themselves before casting and getting to whatever property you need.
Keep in mind, though, that extending Thread is not a recommended practice and if you are intending to get the result of some computation straight from the Runnable object, you could run into some severe trouble if you are not careful.
In any case, recent Java versions (i.e. 1.5+) offer substantial capabilities for concurrency and I suspect that your application would benefit from a re-design that uses them.
We might be able to help more if you explained what exactly you are trying to do in broader terms...
You should consider using the new java.util.concurrent package. What you are trying to do can be implemented a lot easier and intuitively with an ExecutorService and a collection of Callables.
Check out this sample and the Executors API (specifically the fixedThreadPool).

How can I pass a parameter to a Java Thread?

Can anyone suggest to me how I can pass a parameter to a thread?
Also, how does it work for anonymous classes?
You need to pass the parameter in the constructor to the Runnable object:
public class MyRunnable implements Runnable {
public MyRunnable(Object parameter) {
// store parameter for later user
}
public void run() {
}
}
and invoke it thus:
Runnable r = new MyRunnable(param_value);
new Thread(r).start();
For Anonymous classes:
In response to question edits here is how it works for Anonymous classes
final X parameter = ...; // the final is important
Thread t = new Thread(new Runnable() {
p = parameter;
public void run() {
...
};
t.start();
Named classes:
You have a class that extends Thread (or implements Runnable) and a constructor with the parameters you'd like to pass. Then, when you create the new thread, you have to pass in the arguments, and then start the thread, something like this:
Thread t = new MyThread(args...);
t.start();
Runnable is a much better solution than Thread BTW. So I'd prefer:
public class MyRunnable implements Runnable {
private X parameter;
public MyRunnable(X parameter) {
this.parameter = parameter;
}
public void run() {
}
}
Thread t = new Thread(new MyRunnable(parameter));
t.start();
This answer is basically the same as this similar question: How to pass parameters to a Thread object
via constructor of a Runnable or Thread class
class MyThread extends Thread {
private String to;
public MyThread(String to) {
this.to = to;
}
#Override
public void run() {
System.out.println("hello " + to);
}
}
public static void main(String[] args) {
new MyThread("world!").start();
}
This answer comes very late, but maybe someone will find it useful. It is about how to pass a parameter(s) to a Runnable without even declaring named class (handy for inliners):
String someValue = "Just a demo, really...";
new Thread(new Runnable() {
private String myParam;
public Runnable init(String myParam) {
this.myParam = myParam;
return this;
}
#Override
public void run() {
System.out.println("This is called from another thread.");
System.out.println(this.myParam);
}
}.init(someValue)).start();
Of course you can postpone execution of start to some more convenient or appropriate moment. And it is up to you what will be the signature of init method (so it may take more and/or different arguments) and of course even its name, but basically you get an idea.
In fact there is also another way of passing a parameter to an anonymous class, with the use of the initializer blocks. Consider this:
String someValue = "Another demo, no serious thing...";
int anotherValue = 42;
new Thread(new Runnable() {
private String myParam;
private int myOtherParam;
// instance initializer
{
this.myParam = someValue;
this.myOtherParam = anotherValue;
}
#Override
public void run() {
System.out.println("This comes from another thread.");
System.out.println(this.myParam + ", " + this.myOtherParam);
}
}).start();
So all happens inside of the initializer block.
When you create a thread, you need an instance of Runnable. The easiest way to pass in a parameter would be to pass it in as an argument to the constructor:
public class MyRunnable implements Runnable {
private volatile String myParam;
public MyRunnable(String myParam){
this.myParam = myParam;
...
}
public void run(){
// do something with myParam here
...
}
}
MyRunnable myRunnable = new myRunnable("Hello World");
new Thread(myRunnable).start();
If you then want to change the parameter while the thread is running, you can simply add a setter method to your runnable class:
public void setMyParam(String value){
this.myParam = value;
}
Once you have this, you can change the value of the parameter by calling like this:
myRunnable.setMyParam("Goodbye World");
Of course, if you want to trigger an action when the parameter is changed, you will have to use locks, which makes things considerably more complex.
I know that I'm a few years late, but I came across this issue and took an unorthodox approach. I wanted to do it without making a new class, so this is what I came up with:
int x = 0;
new Thread((new Runnable() {
int x;
public void run() {
// stuff with x and whatever else you want
}
public Runnable pass(int x) {
this.x = x;
return this;
}
}).pass(x)).start();
You can either extend the Thread class or the Runnable class and provide parameters as you want. There are simple examples in the docs. I'll port them here:
class PrimeThread extends Thread {
long minPrime;
PrimeThread(long minPrime) {
this.minPrime = minPrime;
}
public void run() {
// compute primes larger than minPrime
. . .
}
}
PrimeThread p = new PrimeThread(143);
p.start();
class PrimeRun implements Runnable {
long minPrime;
PrimeRun(long minPrime) {
this.minPrime = minPrime;
}
public void run() {
// compute primes larger than minPrime
. . .
}
}
PrimeRun p = new PrimeRun(143);
new Thread(p).start();
To create a thread you normally create your own implementation of Runnable. Pass the parameters to the thread in the constructor of this class.
class MyThread implements Runnable{
private int a;
private String b;
private double c;
public MyThread(int a, String b, double c){
this.a = a;
this.b = b;
this.c = c;
}
public void run(){
doSomething(a, b, c);
}
}
Either write a class that implements Runnable, and pass whatever you need in a suitably defined constructor, or write a class that extends Thread with a suitably defined constructor that calls super() with appropriate parameters.
In Java 8 you can use lambda expressions with the Concurrency API & the ExecutorService as a higher level replacement for working with threads directly:
newCachedThreadPool() Creates a thread pool that creates new threads
as needed, but will reuse previously constructed threads when they are
available. These pools will typically improve the performance of programs that execute many short-lived asynchronous tasks.
private static final ExecutorService executor = Executors.newCachedThreadPool();
executor.submit(() -> {
myFunction(myParam1, myParam2);
});
See also executors javadocs.
As of Java 8, you can use a lambda to capture parameters that are effectively final. For example:
final String param1 = "First param";
final int param2 = 2;
new Thread(() -> {
// Do whatever you want here: param1 and param2 are in-scope!
System.out.println(param1);
System.out.println(param2);
}).start();
Parameter passing via the start() and run() methods:
// Tester
public static void main(String... args) throws Exception {
ThreadType2 t = new ThreadType2(new RunnableType2(){
public void run(Object object) {
System.out.println("Parameter="+object);
}});
t.start("the parameter");
}
// New class 1 of 2
public class ThreadType2 {
final private Thread thread;
private Object objectIn = null;
ThreadType2(final RunnableType2 runnableType2) {
thread = new Thread(new Runnable() {
public void run() {
runnableType2.run(objectIn);
}});
}
public void start(final Object object) {
this.objectIn = object;
thread.start();
}
// If you want to do things like setDaemon(true);
public Thread getThread() {
return thread;
}
}
// New class 2 of 2
public interface RunnableType2 {
public void run(Object object);
}
You can derive a class from Runnable, and during the construction (say) pass the parameter in.
Then launch it using Thread.start(Runnable r);
If you mean whilst the thread is running, then simply hold a reference to your derived object in the calling thread, and call the appropriate setter methods (synchronising where appropriate)
There is a simple way of passing parameters into runnables.
Code:
public void Function(final type variable) {
Runnable runnable = new Runnable() {
public void run() {
//Code adding here...
}
};
new Thread(runnable).start();
}
No you can't pass parameters to the run() method. The signature tells you that (it has no parameters). Probably the easiest way to do this would be to use a purpose-built object that takes a parameter in the constructor and stores it in a final variable:
public class WorkingTask implements Runnable
{
private final Object toWorkWith;
public WorkingTask(Object workOnMe)
{
toWorkWith = workOnMe;
}
public void run()
{
//do work
}
}
//...
Thread t = new Thread(new WorkingTask(theData));
t.start();
Once you do that - you have to be careful of the data integrity of the object you pass into the 'WorkingTask'. The data will now exist in two different threads so you have to make sure it is Thread Safe.
One further option; this approach lets you use the Runnable item like an asynchronous function call. If your task does not need to return a result, e.g. it just performs some action you don't need to worry about how you pass back an "outcome".
This pattern lets you reuse an item, where you need some kind of internal state. When not passing parameter(s) in the constructor care is needed to mediate the programs access to parameters. You may need more checks if your use-case involves different callers, etc.
public class MyRunnable implements Runnable
{
private final Boolean PARAMETER_LOCK = false;
private X parameter;
public MyRunnable(X parameter) {
this.parameter = parameter;
}
public void setParameter( final X newParameter ){
boolean done = false;
synchronize( PARAMETER_LOCK )
{
if( null == parameter )
{
parameter = newParameter;
done = true;
}
}
if( ! done )
{
throw new RuntimeException("MyRunnable - Parameter not cleared." );
}
}
public void clearParameter(){
synchronize( PARAMETER_LOCK )
{
parameter = null;
}
}
public void run() {
X localParameter;
synchronize( PARAMETER_LOCK )
{
localParameter = parameter;
}
if( null != localParameter )
{
clearParameter(); //-- could clear now, or later, or not at all ...
doSomeStuff( localParameter );
}
}
}
Thread t = new Thread(new MyRunnable(parameter));
t.start();
If you need a result of processing, you will also need to coordinate completion of MyRunnable when the sub-task finishes. You could pass a call back or just wait on the Thread 't', etc.
Specially for Android
For callback purposes I usually implement my own generic Runnable with input parameter(s):
public interface Runnable<TResult> {
void run(TResult result);
}
Usage is simple:
myManager.doCallbackOperation(new Runnable<MyResult>() {
#Override
public void run(MyResult result) {
// do something with the result
}
});
In manager:
public void doCallbackOperation(Runnable<MyResult> runnable) {
new AsyncTask<Void, Void, MyResult>() {
#Override
protected MyResult doInBackground(Void... params) {
// do background operation
return new MyResult(); // return resulting object
}
#Override
protected void onPostExecute(MyResult result) {
// execute runnable passing the result when operation has finished
runnable.run(result);
}
}.execute();
}
Create a local variable in your class that extends Thread or implements Runnable.
public class Extractor extends Thread {
public String webpage = "";
public Extractor(String w){
webpage = w;
}
public void setWebpage(String l){
webpage = l;
}
#Override
public void run() {// l is link
System.out.println(webpage);
}
public String toString(){
return "Page: "+webpage;
}}
This way, you can pass a variable when you run it.
Extractor e = new Extractor("www.google.com");
e.start();
The output:
"www.google.com"
First I want to point out that other answers are true.
However, using the parameter in the constructor may not be the best idea for all of you.
In many scenarios you will want to use "Anonymous Inner Class", and override the run() method, because defining specific class for every use is painful.
(new MyRunnable(){...})
And at the time you create that Runnable, the parameter may not be available to you to pass it in the constructor. If for example, you pass this object to a method, that will perform some work in separate thread and then call your runnable, applying the result from that work to it.
In that case, using a method like this one:
public MyRunnable withParameter(Object parameter), may turn out to be far more useful choice.
I do not claim that this is the best solution to the problem, but it will get the job done.

Categories