Accessing a variable of a thread from another thread in java - java

I'm trying to access and modify a variable of a thread in another thread in java, and I really don't know how to do this.
ex :
Runnable r1 = new Runnable() {
int value = 10;
public void run() {
// random stuff
}
}
Runnable r2 = new Runnable() {
public void run() {
// of course the bellow line will not work
r1.value--; // I want here to be able to decrement the variable "value" of r1
}
}
Thread t1 = new Thread(r1);
Thread t2 = new Thread(r2);
t1.start();
t2.start();
Is there any way to create a getter and setter for a thread in java?
Edit: the answers were good, but I was not clear in my question, I will try asking a better question

You could make it sort of work but, I suggest you use an AtomicInteger which is shared between threads.
final AtomicInteger value = new AtomicInteger(10);
Runnable r1 = new Runnable() {
public void run() {
// random stuff using value
}
}
Runnable r2 = new Runnable() {
public void run() {
value.decrementAndGet();
}
}
You can use AtomicReference for references to objects.

Create a runnable, and use the setters and getters you define in said runnable.
public class MyRunnable implements Runnable{
private volatile String myString;
public String setString(String value){this.myString = value;}
public String getString(){
return myString;
}
public void run(){}
}
Note volatile keyword is used here. The volatile keyword ensures if this String changes in one thread, that all threads will see the change. If instead I ensure that the only access to the String object is through synchronized context, then the volatile keyword would not be necessary.
To demonstrate my point, the above code and the below code are both thread-safe but are different as no 2 threads can enter setString and getString simultaneously in the example below.
public class MyRunnable implements Runnable{
private String myString;
public synchronized String setString(String value){this.myString = value;}
public synchronized String getString(){
return myString;
}
public void run(){}
}
A thread is really just executing a runnable. You could use this like so:
MyRunnable runnable = new MyRunnable();
Thread myThread = new Thread(runnable);
myThread.start();
String myString = runnable.getString();
Using atomic values for primitives is fine, but if you ever want to share a more complex object, you'll have to read about threading and synchronization.
For example:
public class Stats{
int iterations;
long runtime;
public Stats(){
iterations = 0;
runtime=0;
}
public synchronized void setIterations(int value){this.iterations = value;}
public synchronized void setRuntime(long milliseconds){
this.runtime = milliseconds;
}
public synchronized int getIterations(){
return iterations;
}
public synchronized long getRuntime(){return runtime;}
}
public class StatRunnable implements Runnable{
Stats stats;
boolean active;
public StatRunnable(){
this.active=true;
}
public Stats getStats(){
return stats;
}
long calculateRuntime(){return 0L;}
public void run(){
while(active){
//i'm synchronizing with stats to ensure no other thread alters values
//simultaneously.
synchronized(stats){
stats.setIterations(stats.getIterations()+1);
stats.setRuntime(calculateRuntime());
}
}
}
}
This code shows an example of synchronization with non-primitive objects via the synchronized keyword. Using the synchronized keyword in a method definition locks the class using itself as the synchronizing object.
A final note, the synchronized keyword isn't just used in method definitions. You can use it to synchronize on instances within methods as I've done in the run method in StatRunnable.

Related

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

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
}

List populated in different thread appears empty in caller thread - Java

My code basically goes like this:
//in Main Thread: (myList is a volatile field)
myList = new ArrayList<myClass>();
Thread myThread = new Thread(new MyCustomRunnable(myList));
myThread.start();
//some lines of code NOT involving myList
myThread.join();
//myList appears empty here even though I can see that the list has been populated
//in the other thread
Is there a reason for this behavior? Like I said, i can see in the debugger that the list has been populated in the called thread, but these changes don't appear in the caller thread after the join() method. MyCustomRunnable also declares the ArrayList as a volatile field, assigned by the constructor.
UPDATE:
Ok, I made a simpler program, replacing the ArrayList with a simple Integer and the results are the same...
public class Threading {
private volatile static Integer i = 0;
public static void main(String[] args) throws InterruptedException {
Thread t = new Thread(new MyCustomRunnable(i));
t.start();
t.join();
System.out.println(i); //prints '0', I expected '1'
}
}
public class MyCustomRunnable implements Runnable {
private volatile Integer i;
public MyCustomRunnable(Integer i) {
this.i = i;
}
public void run() {
this.i = 1;
}
}
Why isn't the Integer's value updated in the main Thread?
Add
public static void setI(int i) {
Threading.i = i;
}
to your Threading class and in your runnable add
public void run() {
this.i = 1;
Threading.setI(1);
}
This has nothing to do with multithreading, just variable scoping. i in the Threading class is not updated in MyCustomRunnable's run method.

Is this a good design for implementing the java synchronized keyword as an object?

Just for practice I wanted to implement the java synchronized keyword as a java object.
Would you say the code below is a good design for this?
I guess AtomicReference would have a similar performance to AtomicBoolean?
Updated code after suggestions:
public class SynchronizedBlock implements Runnable{
private final Lock lock;
private final Runnable runnable;
public SynchronizedBlock(Runnable r, Lock l){
runnable = r;
lock = l;
}
public void run() {
try {
while(!lock.compareAndSet(false, true)){
Thread.sleep(100);
}
runnable.run();
} catch (InterruptedException e) {
e.printStackTrace();
} finally {
lock.unlock();
}
}
}
public class Lock {
private final AtomicReference<Boolean> locked = new AtomicReference<Boolean>(false);
public boolean compareAndSet(boolean expected, boolean update){
return locked.compareAndSet(expected, update);
}
public boolean isLocked(){
return locked.get();
}
public void unlock(){
locked.set(false);
}
}
#Test
public void test() {
final SynchronizedBlock sb = new SynchronizedBlock(new Runnable(){
public void run() {
x++;
System.out.println(x);
}
}, new Lock());
Runnable r1 = new Runnable(){
int c = 0;
public void run() {
while(c<10){
sb.run();
c++;
}
}
};
Runnable r2 = new Runnable(){
int c = 0;
public void run() {
while(c<10){
sb.run();
c++;
}
}
};
Thread t1 = new Thread(r1);
Thread t2 = new Thread(r2);
t1.start();
t2.start();
while (t1.isAlive() && t2.isAlive()){
}
assertEquals(20,x);
}
You should add a method to encapsulate the compareAndSwap, and there is no point looping for the lock to be free before attempting to obtain it. Why get in the situation where you can see the lock is free but by the time you try to take it, it is gone.
I would remove the lock method and place the unlock in a finally lock so that an Exception/Error doesn't result in a lock which never unlocks.
Also I would use an AtomicBoolean which is more natural than an AtomicReference
Firstly and most importantly, you should remove Thread.sleep(100). This will cause at least 100ms latency even in only 2-thread contention.
You can simply use AtomicBoolean instead of AtomicReference to simplify your code. Also if you're really concerned about concurrency in high-contention situation, you can modify your code to check if it's locked before doing CAS.
while (true) {
if (lock.isLocked()) continue; // or get() == true if you use AtomicBoolean
if (lock.compareAndSet(false, true))
break;
}
This is an example of TTAS(Test-Test-And-Set) locking which takes advantage of local-spinning to reduce main-memory access while looping.
See http://en.wikipedia.org/wiki/Test_and_Test-and-set

Why does this thread data race?

I am new to threads and learning. Why does this data race? I know how to do it using the Synchronized(){} method but not with the modifier.
public class SyncMethodDataRace extends Thread {
private static int common = 0;
public synchronized void run(){
int local = common;
local++;
common = local;
}
public static void main(String[] args) throws InterruptedException {
SyncMethodDataRace[] allThreads = new SyncMethodDataRace[20000];
for(int i = 0; i < allThreads.length; i++){
allThreads[i] = new SyncMethodDataRace();
}
for(SyncMethodDataRace d: allThreads){
d.start();
}
for(SyncMethodDataRace d: allThreads){
d.join();
}
System.out.println(common);
}
}
By making run method synchronized you did not achieve the desired synchronization. A synchronized method locks on the current instance of the class. In your example, no other thread is calling the run method of another thread, so there is no blocking.
In your case you probably need a static object that is shared among all instances to synchronize on, ie:
private static Object syncObject = new Object();
public void run() {
synchronized (syncObject) {
//....
}
}

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