Change value of a variable x in main method through running thread - java

public static void main(String args[]) throws Exception {
int maxScore = 0;
Thread student = new Thread(client,????);
student.start();
}
I want student thread to change value of maxScore, how do I do it in Java? (Like in C we can pass the address of maxScore)

You need a class object, if you want to modify value in separate thread. For example:
public class Main {
private static class Score {
public int maxScore;
}
public static void main(String args[]) throws Exception {
final Score score = new Score();
score.maxScore = 1;
System.out.println("Initial maxScore: " + score.maxScore);
Thread student = new Thread() {
#Override
public void run() {
score.maxScore++;
}
};
student.start();
student.join(); // waiting for thread to finish
System.out.println("Result maxScore: " + score.maxScore);
}
}

You can't. There is no way you can change the value of a local variable from another thread.
You can, however, use a mutable type that has an int field, and pass it to the new thread. For example:
public class MutableInt {
private int value;
public void setValue(..) {..}
public int getValue() {..};
}
(Apache commons-lang provide a MutableInt class which you can reuse)
Update: for a global variable you can simple use public static fields. Note that if you are willing not only to store some values in them, but also read them and do stuff depending on that, you would need to use synchronized blocks, or AtomicInteger, depending on the usages.

Also, you can use array (of one element):
public class Main {
public static void main(String args[]) throws Exception {
final int[] score = new int[1];
score[0] = 1;
System.out.println("Initial maxScore: " + score[0]);
Thread student = new Thread() {
#Override
public void run() {
score[0]++;
}
};
student.start();
student.join(); // waiting for thread to finish
System.out.println("Result maxScore: " + score[0]);
}
}

adding Synchronized to the methods was a solution for me, thanks

Related

Anonymous thread class not able to access non static instance variables

I am trying to access instance variable inside a Thread anonymous class . I am getting an error here saying to make it static . The point here is if i can access "this" keyword inside the anonymous class which treats it as its current object holder, then why is it not able to access the instance variables in a non static way .
public class AnonymousThreadDemo {
int num;
public AnonymousThreadDemo(int num) {
this.num = num;
}
public static void main(String[] args) {
Thread thread = new Thread() {
#Override
public void run() {
System.out.println("Anonymous " + num); // Why cant we access num instance variable
System.out.println("Anonymous " + this); // This can be accessed in a nonstatic way
}
};
thread.start();
}
}
num is a non static field, it belongs to a specific instance. You can not reference it in static main directly, because a static method can be called without creating an instance.
this is actually referencing thread, it is a local variable, when you execute run, the thread must have been created.
If you try reference AnonymousThreadDemo.this in main, you will get same result:
public static void main(String[] args) {
Thread thread = new Thread() {
#Override
public void run() {
System.out.println("Anonymous " + AnonymousThreadDemo.this); // compile error
}
};
thread.start();
}
This is ok, you can reference a local variable in local class:
public static void main(String[] args) {
int num = 0;
Thread thread = new Thread() {
#Override
public void run() {
System.out.println("Anonymous " + num);
}
};
thread.start();
}
This is ok, you can reference a non static local class field in its method:
public static void main(String[] args) {
Thread thread = new Thread() {
int num = 0;
#Override
public void run() {
System.out.println("Anonymous " + num);
}
};
thread.start();
}
Check this for more.
num is non static that means it will come after static main in the memory. Hence when main will try to point num it won't be available in the memory ie. It still won't be declared yet.

While loop and checking static variable

I have two threads and in one thread I set static variable and in another I check static variable via function like this
Test test= new Test();
while(!Temp.isVarSet()){
}
System.out.println("Variable set");
But this codes hangs - doesn't go to println statement. But the following code works
Test test= new Test();
while(!Temp.isVarSet()){
System.out.println("I am still here");
}
System.out.println("Variable set");
The Temp class
public class Temp {
private volatile static boolean varSet=false;
public synchronized static void setVarSet() {
Temp.varSet=true;
}
public synchronized static boolean isVarSet() {
return Temp.varSet;
}
}
Test class
public class Test{
public Test() {
java.awt.EventQueue.invokeLater(new Runnable() {
public void run() {
Model model= new Model();
View view = new View();
Controller controller=new Controller(model, view);
Temp.setVarSet();
...
}
});
}
}
What can be reason? I set method isVarSet() synchronized but it didn't help.
EDIT
This code works too.
Test test = Test()
while(!Temp.isVarSet()){
Thread.sleep(100);
}
You didn't publish what happens in Temp and isVarSet but most probably you change a variable. This variable must be marked volatile.
If your class looks like this:
public class Temp {
private static boolean someFlag;
public static boolean isVarSet() {
return someFlag;
}
}
And your loop is the same as the example, the compiler thinks that there's no need to read the flag over and over again because the flag is not changed inside the loop and it optimizes to not read the flag over and over.
Marking someFlag as volatile:
private static volatile boolean someFlag;
Will force the runtime to check the flag on each iteration and not just assume that the value hasn't changed. In this case, it will work.
From Oracle docs about atomic access:
Atomic actions cannot be interleaved, so they can be used without fear
of thread interference. However, this does not eliminate all need to
synchronize atomic actions, because memory consistency errors are
still possible. Using volatile variables reduces the risk of memory
consistency errors, because any write to a volatile variable
establishes a happens-before relationship with subsequent reads of
that same variable. This means that changes to a volatile variable are
always visible to other threads. What's more, it also means that when
a thread reads a volatile variable, it sees not just the latest change
to the volatile, but also the side effects of the code that led up the
change.
Even after you made variable as volatile .
if you add SOP in while loop it is working
These two usecase gives me another thought. just try it.
Since your read and write methods are sync , in your while loop
while(!Temp.isVarSet()){
}
It is nothing doing other than calling the method, it may possible this sync method holds the lock on the Temp Object which does not allow other thread to modify the values (though sync setMethod) .
While add SOP inside the while , it is doing some work on IO and thus it is allowing some time slice to other thread get the lock of Temp and modify the same.
Could you please try remove Sync from read method , just for testing purpose and post your results.
public class Temp {
private volatile static boolean varSet=false;
public synchronized static void setVarSet() {
Temp.varSet=true;
}
public static boolean isVarSet() {
return Temp.varSet;
}
}
This works perfect for me:
public class ThreadTest {
public static void main(String[] args) throws Exception {
Thread t1 = new TheThread();
t1.start();
// wait
Thread.sleep(500);
System.out.println(Thread.currentThread().getId() + " will now setVarSet()");
Temp.setVarSet();
System.out.println(Thread.currentThread().getId() + " setVarSet() setted");
t1.join();
System.out.println(Thread.currentThread().getId() + " end programm");
}
private static class TheThread extends Thread {
#Override
public void run() {
System.out.println(Thread.currentThread().getId() + " enter run");
while (!Temp.isVarSet()) {
System.out.println(Thread.currentThread().getId() + " running");
try {
Thread.sleep((int) (Math.random() * 100));
} catch (InterruptedException e) {
// ignore
}
}
System.out.println(Thread.currentThread().getId() + " exit run");
}
}
private static class Temp {
private volatile static boolean varSet = false;
public static void setVarSet() {
Temp.varSet = true;
}
public static boolean isVarSet() {
return Temp.varSet;
}
}
}
Can you please post a complete example?
Its working as expected without hanging the program.
private volatile static boolean varSet = false;
public synchronized static void setVarSet() {
varSet = true;
}
public synchronized static boolean isVarSet() {
return varSet;
}
public static void main(String[] args) throws InterruptedException {
Thread t1 = new Thread(new Runnable() {
#Override
public void run() {
while (!TestDemo.isVarSet()) {
// System.out.println("I am still here");
}
System.out.println("Variable set");
}
});
t1.start();
Thread.sleep(1000); // put delay to give the chance to execute above thread
java.awt.EventQueue.invokeLater(new Runnable() {
public void run() {
// Model model= new Model();
// View view = new View();
// Controller controller=new Controller(model, view);
setVarSet();
}
});
}

Synchronized counter does not count correctly

For each creation of the object, I want it to be uniquely accessible by an identifier. I am using an incrementing static value to keep track of how many objects have been created, and every time a new one is constructed, I make its identifier equivalent to count + 1 (and increment the count). The problem I am encountering is that synchronization is not working. Here is a simplified version of the code:
public static final Hashtable MODULES = new Hashtable();
private static final Object countLock = new Object();
private static int count = 0;
private final String identifier;
private final String name;
public Class(String name) {
this.identifier = String.valueOf(incrementCount());
this.name = name;
MODULES.put(identifier, name);
}
private static int incrementCount() {
synchronized (countLock) {
return ++count;
}
}
Now when I test with this (unrealistically, admittedly, but to be sure that it works):
for (int x = 0; x < 100; x++) {
new Thread(new Runnable() {
#Override
public void run() {
Class m = new Class("Name");
}
}).start();
}
System.out.println(Module.MODULES.size());
I get output anywhere from the 60's to 100. Obviously I don't want that sort of unreliability. Would a volatile field work here? (I have tried with the same results) I am not sure how to make sure every class object has a different identifier. Any solutions are welcome.
Note: I do not access to java.util.concurrent for implementation specific reasons.
Your lock is working fine but the problem is something different. You are initializing the each object through a new Thread. While the threads are running in background, the main thread, prints the count at moment. Put an appropriate delay in between, you will see the proper count.
public static void main(String[] args) throws InterruptedException{
for (int x = 0; x < 100; x++) {
new Thread(new Runnable() {
#Override
public void run() {
Counter m = new Counter("Name");
}
}).start();
}
Thread.sleep(1000);//put a delay
System.out.println(MODULES.size());
}
Try this:
for (int x = 0; x < 100; x++) {
new Thread(new Runnable() {
#Override
public void run() {
Class m = new Class("Name");
}
}).start();
}
Thread.sleep(500);
System.out.println(Module.MODULES.size());
You are printing the size of hashtable which is not synchronized.
add a synchronized statement before the statement MODULES.put(identifier, name);
synchronized (MODULES) {
MODULES.put(identifier, name);
}
it works for me.
Here is what I see as a problem in your code: The statement Class m = new Class("Name"); is in the run() function, and not in the constructor of Runnable's implementation in your code.
If I have to write a similar code, I would write it this way:
public class ModuleTest {
public static void main(String[] args) {
for (int x = 0; x < 100; x++) {
new Thread(new Runnable() {
{
Module m = new Module("Name");
}
#Override
public void run() {
// do something
}
}).start();
}
System.out.println(Module.MODULES.size());
}
}
Look at the placement of statement Module m = new Module("Name"); above. It is not in run() function, as run() is called when start() is called. That statement is between unnamed braces {} that is called during construction of the anonymous implementation of Runnable you have in your code.
And to complete the above code, here is the Module class:
import java.util.Hashtable;
public class Module {
public static final Hashtable MODULES = new Hashtable();
private static final Object countLock = new Object();
private static int count = 0;
private final String identifier;
private final String name;
public Module(String name) {
this.identifier = String.valueOf(incrementCount());
this.name = name;
MODULES.put(identifier, name);
}
private synchronized static int incrementCount() {
return ++count;
}
}

Threads calling both static and non-static method

Disclaimer: This code is copied from synchronized blocks for static and non-static methods
I made some modification to it. I want to know how to make threads call both synchronized static and non-static methods. I can make it work by wrapping the non-static method in a synchronized block. Is there any other way?
public class StaticNonStaticSynch
{
public static void main(String[] args)
{
final StaticNonStaticTest staticNonStaticTest = new StaticNonStaticTest();
Runnable runnable1 = new Runnable()
{
#Override
public void run()
{
staticNonStaticTest.nonStaticMethod();
}
};
Runnable runnable2 = new Runnable()
{
#Override
public void run()
{
StaticNonStaticTest.staticMethod();
}
};
Thread thread1 = new Thread(runnable1, "First Thread");
Thread thread2 = new Thread(runnable2, "Second Thread");
thread1.start();
thread2.start();
}
}
class StaticNonStaticTest
{
void nonStaticMethod()
{
//synchronized (StaticNonStaticTest.class){
for(int i=0;i<50;i++)
{
System.out.println("Non - Static method called by " + Thread.currentThread().getName() +" : = "+i);
}
// }
}
static synchronized void staticMethod()
{
for(int i=0;i<50;i++)
{
System.out.println("Static method called by " + Thread.currentThread().getName() +" : = "+i);
}
}
}
Remember that this:
public class MyClass {
public synchronized void doSomething() {
// Do something
}
public synchronized static void doSomethingStatic() {
// Do something static
}
}
Essentially compiles to this:
public class MyClass {
public void doSomething() {
synchronized(this) {
// Do something
}
}
public static void doSomethingStatic() {
synchronized(MyClass.class) {
// Do something static
}
}
}
Notice that they don't synchronize on the same thing. To fix this, create an object for both of them to lock on (known as a mutually exclusive object, or a "mutex"):
public class MyClass {
private static final Object MUTEX = new Object();
public void doSomething() {
synchronized(MUTEX) {
// Do something
}
}
public static void doSomethingStatic() {
synchronized(MUTEX) {
// Do something static
}
}
}
That should make it so that only one of these two methods are running at the same time across multiple threads.
A couple tips:
Always use synchronized(variable) on a variable that's final.
The MUTEX doesn't have to be strictly a mutex, it could be an actual object. See the example below.
Remember how the synchronized modifier on methods is effectively implemented. It's just like a synchronized block on this or MyClass.class.
Besides having an object that's strictly a mutex, you can use any field that's final. For example, to synchronize on a Map during iteration:
public class MyClass {
private static final Map<String, String> map = new HashMap<String, String>(); // Java 6
private static final Map<String, String> map = new HashMap<>(); // Java 7
public static void put(String k, String v) {
synchronized(map) {
map.put(k, v);
}
}
public static void printAll() {
synchronized(map) {
for (Entry<String, String> entry : map.entrySet()) {
System.out.println(entry.getKey() + ":" + entry.getValue());
}
}
}
}
This code guarantees that you'll never get a ConcurrentModificationException
You can have both methods internally synchronize on a common lock object. Otherwise, the only way to have the instance method block while the static method executes is to synchronize on the class object (as you have in the commented lines).
Synchronized instance methods synchronize on the object instance; synchronized static methods synchronize on the class instance. Note that synchronized static methods might execute simultaneously if there are two instances of the class (say, from different class loaders). You usually would know if this is happening, because you have to do considerable work to make it happen.
Here's one way to synchronize both static and instance methods on a common lock object:
class StaticNonStaticTest {
private static final Object LOCK_OBJECT = new Object();
void nonStaticMethod() {
synchronized (LOCK_OBJECT) {
for (int i=0; i<50; i++) {
System.out.println("Non - Static method called by "
+ Thread.currentThread().getName() + " : = " + i);
}
}
}
static void staticMethod() {
synchronized (LOCK_OBJECT) {
for (int i=0; i<50; i++) {
System.out.println("Static method called by "
+ Thread.currentThread().getName() +" : = "+i);
}
}
}
}

I want the main method to print out the value x, which is returned by running threads

I want the main method to print out the value x, which is returned by running threads. How can I do it? Hope that my question makes sense.
import java.*;
public class ServerStudentThread extends Thread
{
public ServerStudentThread(Socket x) {
client = x;
}
public void run()
{
//Do something here and return an integer,
// for example **x**
}
public static void main(String args[]) throws Exception {
// ...
// I want to print out x value here.
// But as you can see, x disappears after thread finish its job.
}
}
You would have to make x a field in the ServerStudentThread class, not a local variable. then add a method in the class like getValue() that returns x. From the main method, after you create the thread, run it, call the getValue() mehod on the class to print get the value of x and print it.
If you are using java 5 there is an Callable Interface.kindly look at this link
http://java-x.blogspot.com/2006/11/java-5-concurrency-callable-and-future.html
// Code pasted from the link
public class CallableTester {
public static void main(String[] args) {
Callable<Integer> callable = new CallableImpl(2);
ExecutorService executor = new ScheduledThreadPoolExecutor(5);
Future<Integer> future = executor.submit(callable);
try {
System.out.println("Future value: " + future.get());
} catch (Exception e) {
e.printStackTrace();
}
}
}
public class CallableImpl implements Callable<Integer> {
private int myName;
CallableImpl(int i){
myName = i;
}
public Integer call() {
for(int i = 0; i < 10; i++) {
System.out.println("Thread : " + getMyName() + " I is : " + i);
}
return new Integer(getMyName());
}
public int getMyName() {
return myName;
}
public void setMyName(int myName) {
this.myName = myName;
}
}
You should create thread (call Thread t = new ServerStudentThread(), then call t.start() then you should wait until the tread is done. For example call t.join().

Categories

Resources