Make a copy object of anonymous thread - java

I am new to multi-threading,
and I am currently work on passing a parameter into a Thread.
public class MyRunnable<T> implements Runnable{
protected T obj;
public MyRunnable(){
obj= null;
}
#Override
public void run(){
//do something
}
public void setObj(T obj){
this.obj=obj;
}
public T getObj(){
return obj;
}
}
And I am try to initialize a MyRunnable obj with specify task
within the public void run , like this.
someMethod(new MyRunnable<someType>(){
public void run(){
// do some jobs 1.
// do some jobs 2.
}
});
I want to use this runnable object for different threads with different obj value,
so is it possible to make a deep copy with the same run method?
Thanks in advance!
edit:
the original MyRunnable().run() does nothing, and the task is implemented within the anonymous block, is it any work around to make the copy with the same implemented run() method?

You can make a copy constructor
public MyRunnable(MyRunnable myRunnable) {
this.fieldA = myRunnable.fieldA;
this.felddB = myRunnable.fieldB;
// etc
}
Because you'd be using a different object (with all of the other fields being the same), modify the constructor to reflect this
public MyRunnable(T obj, MyRunnable myRunnable) {
this.obj = obj;
this.fieldA = myRunnable.fieldA;
this.felddB = myRUnnable.fieldB;
// etc
}

You could create a method that returns a particular type of MyRunnable:
public MyRunnable<SomeType> getRunnableForSomePurpose(){
return new MyRunnable<SomeType>(){
public void run(){
//do some jobs
}
}
}
Then call that method each time you need a MyRunnable with that specific run method:
someMethod(getRunnableForSomePurpose());

Related

sending a variable into a thread

I wanted to use an array in a thread but I don't know where to put it so that the new thread accepts it and uses it in the run method
My code so far is
public void game (Button[] temp) {
Thread check = new Thread(new startGame());
check.start();
}
class startGame implements Runnable {
startGame() {}
public synchronized void run() {
if (temp[0].getDrawingCacheBackgroundColor() == temp[1].getDrawingCacheBackgroundColor() )
{
temp[0].setVisibility(View.INVISIBLE);
temp[1].setVisibility(View.INVISIBLE);
}
}
}
I pretty sure I have to put temp inside startGame() but where in the startGame class do I put temp so that I can use it in the if statement?
Try placing it inside your startGame class which should be named StartGame. Passing it in the constructor and setting a class variable to the value.
public void game (Button[] temp) {
Thread check = new Thread(new startGame(temp));
check.start();
}
class startGame implements Runnable {
private Button[] temp
startGame(Button[] temp) {
this.temp=temp;
}
public synchronized void run() {
if (temp[0].getDrawingCacheBackgroundColor() == temp[1].getDrawingCacheBackgroundColor() )
{
temp[0].setVisibility(View.INVISIBLE);
temp[1].setVisibility(View.INVISIBLE);
}
}
}
ug_ is correct. Make it a class variable, set some locks if it's shared, and access it like any other class variable.
But as Ashton Engberg astutely pointed out in a comment, you cannot modify UI elements from outside the UI thread.

Synchronize Protection Not Working for Dual Threads

Below is my stripped down java code for review. I have several subclasses, and when execParallel() is called, a new thread is launched. This thread and the default thread must both execute criticalFunction() several times via actionFunction(), but this function will only work properly for a given SubClassC connection if executed by only one process at a time.
I have used the keyword "synchronized" to guard against concurrent executions, however in practice the criticalFunction() is in fact being called by both threads at the same time.
Any idea What I am doing wrong?
public class MainClass extends GlobalLibrary {
public static SubClassA masterObj;
public MainClass() {
masterObj = new SubClassA();
}
public static class SubClassA {
public SubClassB subObj1;
public SubClassB subObj2;
public SubClassA() {
subObj1 = new SubClassB();
subObj2 = new SubClassB();
}
}
public static class SubClassB {
public SubClassC conObj;
public Thread ut = null;
public SubClassB() {
conObj = new SubClassC();
}
}
public static class SubClassC {
public TCPMasterConnection con=null;
public SubClassC() {
con = new TCPMasterConnection();
}
public synchronized Object criticalFunction(int arg) {
return otherClass.executeCritical(con, arg);
}
}
public boolean actionFunction(SubClassB subObj, int arg) {
return (subObj.conObj.criticalFunction(arg)==null);
}
public class ActionThread implements Runnable {
public SubClassB subObj;
private int icode;
public ActionThread(SubClassB arg1, int arg2) {
subObj = arg1;
icode = arg2;
}
public void run() {
for (int i=0; i<10; i++) actionFunction(subObj, icode);
}
}
public void execParallel() {
masterObj.subObj1.ut = new Thread(new ActionThread(masterObj.subObj1, 1));
masterObj.subObj1.ut.start();
actionFunction(masterObj.subObj1, 2);
actionFunction(masterObj.subObj1, 3);
actionFunction(masterObj.subObj1, 4);
actionFunction(masterObj.subObj1, 5);
actionFunction(masterObj.subObj1, 6);
}
}
If your goal is to protect the otherClass.executeCritical(con, arg) invocation, then you'll want to lock at the granularity of the otherClass instance. If the goal is to have only one thread using the "master connection" at a given time, which seems like it would be something you very much want, then you need the locking granularity to be at the instance of TCPMasterConnection. In the latter case, your code would look like this:
public Object criticalFunction(int arg) {
synchronized(con) {
return otherClass.executeCritical(con, arg);
}
}
Now if you have multithread-unsafe code in both otherClass and con (of TCPMasterConnection), you'll maybe want a lock with larger granularity. In that case, an easy thing might be to lock at the class level as described in other answers.
You are calling criticalFunction() on different instances so they are using different locks. You need to share a lock between all instances.
Try this
public Object criticalFunction(int arg) {
synchronized (SubClassC.class) {
return otherClass.executeCritical(con, arg);
}
}
Whether part of your code that you want to synchronize, make this instead:
Object lock = new Object();
public void doSomething{
synchronized(lock){
//your code
}
}
Synchronized methods only work at the instance level.

How to get the variables out of a new thread?

How can i get the variables out of a new thread created with:
public class ParseJson
{
public static String parsejson(String strHttpGet)
{
Thread thread = new Thread(new Runnable()
{
public String run(String strHttpGet)
{
String decodeJson = "someJson";
return decodeJson;
}
});
thread.start();
}
}
I mean how can i get back the decoded json to my function parseJson and give it back to my function call String decodedJson = ParseJson.parseJson(strHttpGet);?
In android, which you have tagged this question as, it would be simpler to use AsyncTask for this situation, because when you override the onPostEXecute method you can put in all sorts of things:
update the UI
send intents and messages
access variables of the parent class if the AsyncTask class is defined inside it.
class MyClass {
Button b;
boolean flag = false;
// Stuff
class MyAsyncClass extends AsyncTask {
// All the stuff, core work in doInBackground
#Override
void onPostExecute(/*vars*/) {
b.setText("Done");
flag = true;
}
}
}
General principles for using AsyncTask: http://developer.android.com/reference/android/os/AsyncTask.html
tutorial: http://samir-mangroliya.blogspot.co.uk/p/android-asynctask-example.html
tutorial: http://androidresearch.wordpress.com/2012/03/17/understanding-asynctask-once-and-forever/
You can't return a value from a Thread in Java. Actually, run() doesn't have a return type.
You could use a shared custom Object that will hold the result. Declare it as final, so you can access it in the anonymous subclass (that would be equivalent to passing a reference to the subclass), and just call a setter on it when the work is done.
public class ParseJson {
public static String parsejson(final String strHttpGet) {
final StringHolder ob = new MyObject();
Thread thread = new Thread() {
public String run() {
String decodeJson = "someJson";
ob.setResult(decodeJson);
}
};
thread.start();
}
private static class StringHolder (){
private String result;
public String getResult() { return result; }
public void setResult(String r) { result = r; }
}
}
I'm not sure I understood why you said get back the decoded json to my function parseJson and give it back to my function call. Do you mean you'll just wait in that function until the Thread is finished? If that's what you want (again, why start a Thread?), you could use Thread.join().
Although if you want to get notified when the Thread finishes, you should indeed look into another option. Neil and Waqas have given good approaches.
You may even use an Observer/Observable pattern for this.
You could use a Future
public class Json {
private static final ExecutorService executor = Executors.newCachedThreadPool();
public static String parse(final String strHttpGet)
throws TimeoutException, InterruptedException, ExecutionException {
Future<String> jsonTask = executor.submit(new Callable<String>() {
#Override
public String call() throws Exception {
String decodeJson = decodeJson(strHttpGet);
return decodeJson;
}
private String decodeJson(String strHttpGet) {
// TODO do actual parsing
return null;
}
});
// Allow the parsing to take one second
return jsonTask.get(1, TimeUnit.SECONDS);
}
}

Multiple Runnable in a single thread -java

I am trying to have a bunch of runnable threads that can be started one at a time.
Something like
First(new Thread() {
public void run() {
//do something
}
});
Is what I'm trying to do impossible?
You can use a single threaded Executor
ExecutorService service = Executors.newSingleThreadedPool();
service.submit(runnable1);
service.submit(runnable2);
service.submit(runnable3);
i want to have several runnables in one thread. they will be doing different things at different times.
This sounds like a bad design to me. If your class is doing different things at different times then it should be split into different classes.
If you are talking about re-using the same background thread to do different things, then I would use a single threaded pool as in #Peter's answer:
private ExecutorService threadPool = Executors.newSingleThreadedPool();
...
threadPool.submit(new First());
threadPool.submit(new Second());
threadPool.submit(new Third());
...
// when you are done submitting, always shutdown your pool
threadPool.shutdown();
The First, Second, and Third classes would implement Runnable. They can take constructor arguments if they need to share some state.
Yes, just have multiple private methods:
public class FirstCaller {
private void method1() { }
private void method2() { }
private void method3() { }
public void someMethod() {
First(new Thread() {
public void run() {
//do something
method1();
method2();
method3();
}
});
}
}
OR as pointed out by Ted Hopp
public class FirstCaller {
public void someMethod() {
new First(new Thread() {
private void method1() { }
private void method2() { }
private void method3() { }
public void run() {
//do something
method1();
method2();
method3();
}
});
}
}
If you want to start a few threads at the same time CountDownLatch is what you need. See an example here: http://www.javamex.com/tutorials/threads/CountDownLatch.shtml.
Are you trying to execute multiple runnables sequentially in a single Thread? One after the other?
public class MultiRunnable implements Runnable {
private Runnable runnable1;
private Runnable runnable2;
public MultiRunnable(Runnable runnable1, Runnable runnable2) {
this.runnable1 = runnable1;
this.runnable2 = runnable2;
}
#Override
public void run() {
runnable1.run();
runnable2.run();
}
}
You could then call (new Thread(new MultiRunnable(... , ...))).start();
This will execute the first Runnable first, and when that is finnished it will execute the second.
Or generalised to more Runnables:
import java.util.Arrays;
import java.util.List;
public class MultiRunnable implements Runnable {
private List<Runnable> runnables;
public MultiRunnable(Runnable... runnables) {
this.runnables = Arrays.asList(runnables);
}
public MultiRunnable(List<Runnable> runnables) {
this.runnables = runnables;
}
#Override
public void run() {
for(Runnable runnable : runnables)
runnable.run();
}
}
The easiest thing to do is to define several Thread subclass instances and call the appropriate one depending on what you are trying to do.
However, if you really need a single Thread object that behaves differently in different circumstances, you can define a Thread subclass that has a state variable for controlling what it does.
class MyThread extends Thread {
public enum Action { A, B, C }
private Action mAction;
public void run() {
if (mAction == null) {
throw new IllegalStateException("Action must be specified");
}
switch (mAction) {
case A:
methodA();
break;
case B:
methodB();
break;
case C:
methodC();
break;
}
}
public void setAction(Action action) {
if (action == null) {
throw new IllegalArgumentException("Action cannot be null");
}
mAction = action;
}
private void methodA() { ... }
private void methodB() { ... }
private void methodC() { ... }
}
You could then create your thread and before calling start(), call setAction, passing one of the Action values.
As an alternative to a state variable, the run() method could examine external variables to determine the choice of action. Whether this makes sense (and whether it would be better) depends on your application.

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