Value gets overwritten in Runnable class - Java - java

I am facing a problem with a Runnable class. The value that is passed to the runnable class is overwritten by the last value it received when the same value is passed to another class.
The function of the runnable class is to pass the values to another function in another class to print them. But only the last value received by the Runnable class is printed.
Here is my code,
This is the main class from where the values are passed.
public class MainClass {
private int intVal = -1;
public void MainMethod() {
ExecutorUtil theExecutor = ExecutorUtil.GetInstance();
for(int i = 0; i < 3; i++) {
intVal = i;
synchronized (this) {
theExecutor.SubmitTask(new ActionExecutor(intVal));
}
}
}
}
This is the executorUtil that I use to call the thread.
import java.util.concurrent.ExecutorService;
import java.util.concurrent.LinkedBlockingQueue;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.BlockingQueue;
public class ExecutorUtil {
private static ExecutorUtil theInstance;
private ExecutorService theExecutor;
private BlockingQueue<Runnable> theQueue;
protected ExecutorUtil() {
theExecutor = CreateThreadPoolExecutor();
}
private ExecutorService CreateThreadPoolExecutor() {
theQueue = new LinkedBlockingQueue<Runnable>();
ThreadPoolExecutor threadPoolExecutor = new ThreadPoolExecutor(10, 10, 900, java.util.concurrent.TimeUnit.SECONDS, theQueue);
threadPoolExecutor.allowCoreThreadTimeOut(true);
return threadPoolExecutor;
}
public static ExecutorUtil GetInstance() {
if (theInstance == null) {
synchronized(ExecutorUtil.class) {
if (theInstance == null) {
theInstance = new ExecutorUtil();
}
}
}
return theInstance;
}
public void SubmitTask(Runnable runnable) {
theExecutor.submit(runnable);
}
}
This is the thread that passes the received value to the function that prints these values.
public class ActionExecutor implements Runnable {
int iVal = -1;
public ActionExecutor(int iVal) {
this.iVal = iVal;
}
public void run() {
SecondClass sc = new SecondClass();
sc.printIntVal(iVal);
}
}
And this is the class that prints the values.
public class SecondClass {
public void printIntVal(int i) {
System.out.println(i);
}
}
Expected Output:
0
1
2
Obtained Output:
2
2
2
No idea why this is behaving in this way!
UPDATE:
The issue occurs only when a non-primitive data type is used. In my example here, I've used an integer value (intVal). Since java passes the value for primitive data types, the output was obtained as expected. But in my original code, I've used a JSONObject. And since java passes the reference of the object for non-primitive data types, the value was over-written.
I have solved this by creating new JSONObject for each iteration.

It seems that somewhere you have static field, which store your number.
So, I suppose, that you have 3 instances of ActionExecutor, but it looks like field has static modifier, so each of this instance will have latest value.
Check this case...

So after I read your question and studied your code I might as well try it out. And lo and behold it's working as expected. The only difference here is that there is a race condition so the output my vary in order, but it will not print the same numbers.
Output might
1st: 0 1 2
2nd: 0 1 2
3rd: 2 1 0
Here is the full code to try it out:
import java.util.concurrent.BlockingQueue;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.LinkedBlockingQueue;
import java.util.concurrent.ThreadPoolExecutor;
public class MainClass {
private int intVal = -1;
public void MainMethod() {
ExecutorUtil theExecutor = ExecutorUtil.GetInstance();
for(int i = 0; i < 3; i++) {
intVal = i;
synchronized (this) {
theExecutor.SubmitTask(new ActionExecutor(intVal));
}
}
}
public class ActionExecutor implements Runnable {
int iVal = -1;
public ActionExecutor(int iVal) {
this.iVal = iVal;
}
public void run() {
SecondClass sc = new SecondClass();
sc.printIntVal(iVal);
}
}
public class SecondClass {
public void printIntVal(int i) {
System.out.println(i);
}
}
public static class ExecutorUtil {
private static ExecutorUtil theInstance;
private ExecutorService theExecutor;
private BlockingQueue<Runnable> theQueue;
protected ExecutorUtil() {
theExecutor = CreateThreadPoolExecutor();
}
private ExecutorService CreateThreadPoolExecutor() {
theQueue = new LinkedBlockingQueue<Runnable>();
ThreadPoolExecutor threadPoolExecutor = new ThreadPoolExecutor(10, 10, 900, java.util.concurrent.TimeUnit.SECONDS, theQueue);
threadPoolExecutor.allowCoreThreadTimeOut(true);
return threadPoolExecutor;
}
public static ExecutorUtil GetInstance() {
if (theInstance == null) {
synchronized(ExecutorUtil.class) {
if (theInstance == null) {
theInstance = new ExecutorUtil();
}
}
}
return theInstance;
}
public void SubmitTask(Runnable runnable) {
theExecutor.submit(runnable);
}
}
public static void main(String[] args) {
MainClass main = new MainClass();
main.MainMethod();
}
}
You might want to clean and rebuild your project. Otherwise it's working..

Related

Java save thread result in a variable from main class

I have a thread created by implementing the Runnable interface. My task is this: the thread should count (starting from 0) and save the value it has reached to a variable which is part of the main class. I overrode the run method and did the counting but how I can save this value to the main's variable? Only with a getter is the solution?
My thread class:
public class myThread implements Runnable {
private static int count = 0;
private final int length;
public myThread (int length) {
this.length = length;
}
#Override
public void run() {
while (count < this.length) {
increaseValue();
}
}
private void increaseValue() {
synchronized (ThreadFirstExercise.class) {
if (count < this.length) {
this.count++;
}
}
}
}
main:
public class Main {
public static void main(String[] args) {
int result; // this is the variable where I want to save the counting result of my thread
(new Thread(new ThreadFirstExercise(10000))).start();
}
}
You can either use a Callable that returns a Future.
Or you could use a wrapper Object in the main method that contains the integer.

why DCL use volatile ,not use final?i code run same effect

package test1;
import java.util.Random;
public class OneInstanceService {
// use volatile or final,them has same effect,
// but difference volatile or final in DCL demo?
public int i_am_has_state;
private static OneInstanceService test;
private OneInstanceService() {
i_am_has_state = new Random().nextInt(200) + 1;
}
public static OneInstanceService getTest1() {
if (test == null) {
synchronized (OneInstanceService.class) {
if (test == null) {
test = new OneInstanceService();
}
}
}
return test;
}
public static void reset() {
test = null;
}
}
//----------------------------------------
package test1;
import java.util.concurrent.CountDownLatch;
public class Test1 {
public static void main(String[] args) throws InterruptedException {
for (;;) {
CountDownLatch latch = new CountDownLatch(1);
CountDownLatch end = new CountDownLatch(100);
for (int i = 0; i < 100; i++) {
Thread t1 = new Thread() {
#Override
public void run() {
try {
latch.await();
OneInstanceService one = OneInstanceService.getTest1();
if (one.i_am_has_state == 0) {
System.out.println("one.i_am_has_state == 0 process exit");
System.exit(0);
}
end.countDown();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
};
t1.start();
}
latch.countDown();
end.await();
OneInstanceService.reset();
}
}
}
only use :
public int i_am_has_state;
run result is :
System.out.println("one.i_am_has_state == 0 process exit");
System.exit(0);
but modify code bottom:
volatile public int i_am_has_state;
or
final public int i_am_has_state;
no run bottom code:
System.out.println("one.i_am_has_state == 0 process exit");
System.exit(0);
i question is :
DCL use final ok
DCL use final volatile ok
so
in DCL final and volatile difference?
thank you very much !
final and volatile cannot go together because they are purposefully opposite.
either you have a static field initialized once upon class init:
static final Object x;
static {
x = ...
}
or you have a volatile static field that multiple thread can race to set (your case).
It must be volatile for the double check idiom to work (with the new volatile semantic since jdk 1.5). Since then, the volatile has memory barriers preventing reordering of instructions involving other variables, which somehow (I can't recall that stuff now...) makes the ugly DCL work again... but doesn't make it less ugly.
(I never needed to use the DCL; without DCL, synchronization is still essentially uncontended because the if(x==null) is so fast.)
thank all, bottom not answer.
I modify code:
package test1;
import java.util.Random;
public class OneInstanceService {
final public int i_am_has_state;
volatile private static OneInstanceService test;
private OneInstanceService() {
i_am_has_state = new Random().nextInt(200) + 1;
}
public static OneInstanceService getTest1() {
if (test == null) {
synchronized (OneInstanceService.class) {
if (test == null) {
test = new OneInstanceService();
}
}
}
return test;
}
public static void reset() {
test = null;
}
}
Just had a sudden inspiration, the code is so perfect? I think I'm really getting mixed up.
shmosel:Forgive me for not formatting code and hightline, thank you very much.

counter in runnable 'local variables referenced from an inner class must be final or effectively final'

I need a counter inside of my runnable, I tried writing something that looks like
public class Foo {
private class Bar {
public void barMethod() {
int counter = 0;
Bar instance = this;
BukkitTask barTask = new BukkitRunnable() {
#Override
public void run() {
if (counter == 5) {
this.cancel();
return;
}
instance.doStuff(); // don't worry it exists
counter++;
}
}.runTaskTimer(this.plugin, 0L, 2L);
}
}
}
However, trying to compile it results in the error
local variables referenced from an inner class must be final or effectively final
So I see that the problem is I try to update the counter variable from inside the runnable.
However, that leaves me clueless as to how I can have a counter on the runnable.
How can I make sure the runnable only runs maximum 5 times?
The standard workaround is to replace with a single-element array:
public class Foo {
private class Bar {
public void barMethod() {
int[] counter = new int[] { 0 };
Bar instance = this;
BukkitTask barTask = new BukkitRunnable() {
#Override
public void run() {
if (counter[0] == 5) {
this.cancel();
return;
}
instance.doStuff(); // don't worry it exists
counter[0]++;
}
}.runTaskTimer(this.plugin, 0L, 2L);
}
}
}
The variable itself is never reassigned, so it's effectively final.
You can fix this error this way:
public class Foo {
private class Bar {
public void barMethod() {
Bar instance = this;
BukkitTask barTask = new BukkitRunnable() {
int counter = 0;
#Override
public void run() {
if (counter == 5) {
this.cancel();
return;
}
instance.doStuff(); // don't worry it exists
counter++;
}
}.runTaskTimer(this.plugin, 0L, 2L);
}
}
}
Sincerely

How to switch between two thread back and forth

I have two methods in two different classes, like this
public class ClassX implements Runnable {
public void methodAandB() {
for(int i=0;i<10;i++) {
System.out.println("This is A and B ");
}
}
#Override
public void run() {
methodAandB();
}
}
public class ClassY implements Runnable {
public void methodAorB() {
for(int i=0;i<10;i++) {
System.out.println("This is A or B");
}
}
#Override
public void run() {
methodAorB(a);
}
}
Thread t1 is calling methodAandB().
Thread t2 is calling methodAorB().
Can I switch between these two threads after each iteration of loop in methods?
I want to get output like this:
This is A and B
This is A or B
This is A and B
This is A or B
This is A and B
This is A or B
This is A and B
This is A or B
Best example of flip-flop between threads:
Given two int array (even and odd), 2 threads printing their numbers in natural order.
package com.rough;
public class ThreadsBehaviour {
static Object lock = new Object();
public static void main(String[] args) throws InterruptedException {
int a[] = {1,3,5,7,9};
int b[] = {2,4,6,8,10};
Thread odd = new Thread(new Looper(a, lock));
Thread even = new Thread(new Looper(b, lock));
odd.start();
even.start();
}
}
class Looper implements Runnable
{
int a[];
Object lock;
public Looper(int a[], Object lock)
{
this.a = a;
this.lock = lock;
}
#Override
public void run() {
for(int i = 0; i < a.length; i++)
{
synchronized(lock)
{
System.out.print(a[i]);
try
{
lock.notify();
if(i == (a.length - 1))
{
break;
}
lock.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
}
You can achieve this simply by using the shared variables. I have implemented and verified the problem. code is below
class X
public class ClassX implements Runnable {
public void methodAandB() {
for(int i=0;i<10;i++) {
while(GlobalClass.isClassXdone)
{}
System.out.println("This is A and B ");
GlobalClass.isClassXdone = true;
GlobalClass.isClassYdone = false;
}}
#Override
public void run() {
methodAandB(); } }
ClassY
public class ClassY implements Runnable {
public void methodAorB() {
for(int i=0;i<10;i++) {
while(GlobalClass.isClassYdone)
{}
System.out.println("This is A or B ");
GlobalClass.isClassYdone = true;
GlobalClass.isClassXdone = false;}}
#Override
public void run() {
methodAorB();}}
Definition of the shared variable
public class GlobalClass {
public static boolean isClassXdone = false ;
public static boolean isClassYdone = false ;
}
You can just start your thread using t1.start and t2.start to get the desired output
Thread t1 = new Thread(new ClassX());
Thread t2 = new Thread(new ClassY());
t1.start();
t2.start();
This is probably more than needed to solve the problem, but, as it seems to be an introduction to concurrent programming exercise, it should be along the lines of what you'll encounter.
You should probably have a shared object that both your threads know, so that they may synchronize through it. Like so:
public class MyMutex {
private int whoGoes;
private int howMany;
public MyMutex(int first, int max) {
whoGoes = first;
howMany = max;
}
public synchronized int getWhoGoes() { return whoGoes; }
public synchronized void switchTurns() {
whoGoes = (whoGoes + 1) % howMany;
notifyAll();
}
public synchronized void waitForMyTurn(int id) throws
InterruptedException {
while (whoGoes != id) { wait(); }
}
}
Now, your classes should receive their respective identifier, and this shared object.
public class ClassX implements Runnable {
private final int MY_ID;
private final MyMutex MUTEX;
public ClassX(int id, MyMutex mutex) {
MY_ID = id;
MUTEX = mutex;
}
public void methodAandB() {
for(int i = 0; i < 10; i++) {
try {
MUTEX.waitForMyTurn(MY_ID);
System.out.println("This is A and B ");
MUTEX.switchTurns();
} catch (InterruptedException ex) {
// Handle it...
}
}
}
#Override
public void run() { methodAandB(); }
}
ClassY should do the same. Wait for its turn, do its action, and then yield the turn to the other.
I know it's a little late to answer this. But it's yesterday only I have come across this question. So I guess it's never too late.. ;)
Solution, as #afsantos mentioned is having a shared object between the two threads and implementing mutual exclusion on the shared object. The shared object could be alternatively locked by the two threads. Two possible implementations are as follows. This is actually more like an extension of #afsantos solution. His work is hereby acknowledged.
Solution 1:
Blueprint of the object that will be shared is as follows.
public class MutEx {
public int whoGoes, howMany;
public MutEx(int whoGoes, int howMany) {
this.whoGoes = whoGoes;
this.howMany = howMany;
}
public synchronized void switchTurns(){
this.whoGoes = (this.whoGoes + 1) % 2;
notifyAll();
}
public synchronized void waitForTurn(int id) throws InterruptedException{
while(this.whoGoes != id)
wait();
}
}
Then, you could implement the ClassX as follows.
public class ClassX implements Runnable {
private final int MY_ID;
private final MutEx MUT_EX;
public ThreadOne(int MY_ID, MutEx MUT_EX) {
this.MY_ID = MY_ID;
this.MUT_EX = MUT_EX;
}
#Override
public void run(){
this.doTheWork();
}
public void doTheWork(){
for(int i = 0; i < 10; i++){
try {
MUT_EX.waitForMyTurn(MY_ID);
System.out.println("This is A and B");
MUT_EX.switchTurns();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
ClassY also will be the same, with whatever the differences you need to be there. Then, in the invocation (i.e. in the main method),
public static void main(String[] args) {
MutEx mutEx = new MutEx(0, 2);
Thread t1 = new Thread(new ClassX(0, mutEx);
Thread t2 = new Thread(new ClassY(1, mutEx));
t1.start();
t2.start();
}
Voila! You have two threads, alternating between each as you need.
Solution 2: Alternatively, you could implement the ClassX & ClassY as follows.
public class ClassX extends Thread{
Here, you are subclassing the java.lang.Thread to implement your requirement. For this to be invoked, change the main method as follows.
public static void main(String[] args) {
MutEx mutEx = new MutEx(0, 2);
ClassX t1 = new ClassX(0, mutEx);
ClassY t2 = new ClassY(1, mutEx);
t1.start();
t2.start();
}
Run this, and you have the same result.
If you don't need to use Thread try this code:
for (int i = 0; i < 20; i++) {
if (i % 2 == 0) {
methodAandB();
} else {
methodAorB();
}
}

ThreadLocal pondering (Or: Is sun's javadoc wrong?)

I've been reading about ThreadLocal, trying to understand how it works and why we need it.
So far what I've been able to learn is the following:
ThreadLocal class allows to hold 1 instance of an object at the thread level
The instance is created by overriding initialValue()
The instance is actually stored in the each thread's HashMap
A common sense usage example can be found here
All seemed fine, until I tried to run the example from the javadoc, the code is provided as following:
import java.util.concurrent.atomic.AtomicInteger;
public class UniqueThreadIdGenerator {
private static final AtomicInteger uniqueId = new AtomicInteger(0);
private static final ThreadLocal < Integer > uniqueNum =
new ThreadLocal < Integer > () {
#Override protected Integer initialValue() {
return uniqueId.getAndIncrement();
}
};
public static int getCurrentThreadId() {
return uniqueId.get();
}
} // UniqueThreadIdGenerator
If I understand this code correctly, calling getCurrentThreadId() should return the correct auto incremented thread number, alas it returns 0 for me. ALWAYS 0, without consideration of how many threads I have started.
To get this working for me I had to change getCurrentThreadId() to read
public static int getCurrentThreadId() {
return uniqueId.get();
}
In which case I am getting correct values.
My code is provided below, what am I missing? (It's not that the javadoc is actually wrong, right??)
package org.vekslers;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicInteger;
public class UniqueThreadIdGenerator extends Thread {
private static final AtomicInteger uniqueId = new AtomicInteger(0);
private static final ThreadLocal <Integer> uniqueNum =
new ThreadLocal <Integer> () {
#Override protected Integer initialValue() {
return uniqueId.getAndIncrement();
}
};
public static int getCurrentThreadId() {
return uniqueNum.get();
}
//////////////////////////////////////////////////
// Testing code...
//////////////////////////////////////////////////
private static volatile boolean halt = false;
public UniqueThreadIdGenerator(String threadName) {
super(threadName);
}
#Override
public void run() {
System.out.println(Thread.currentThread() + " PREHALT " + getCurrentThreadId());
while(!halt)
try {
TimeUnit.SECONDS.sleep(1);
} catch (InterruptedException e) {
}
System.out.println(Thread.currentThread() + " POSTHALT " + getCurrentThreadId());
}
public static void main(String[] args) throws InterruptedException {
Thread t1 = new UniqueThreadIdGenerator("t1");
Thread t2 = new UniqueThreadIdGenerator("t2");
Thread t3 = new UniqueThreadIdGenerator("t3");
Thread t4 = new UniqueThreadIdGenerator("t4");
t3.start();
t1.start();
t2.start();
t4.start();
TimeUnit.SECONDS.sleep(10);
halt = true;
}
} // UniqueThreadIdGenerator
Output:
Thread[t3,5,main] PREHALT 0
Thread[t1,5,main] PREHALT 1
Thread[t2,5,main] PREHALT 2
Thread[t4,5,main] PREHALT 3
Thread[t4,5,main] POSTHALT 3
Thread[t2,5,main] POSTHALT 2
Thread[t1,5,main] POSTHALT 1
Thread[t3,5,main] POSTHALT 0
p.s. Code comments OT or to the point are welcome in comments.
The javadocs are wrong.
http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=6475885
Java 7's javadoc includes
import java.util.concurrent.atomic.AtomicInteger;
public class ThreadId {
// Atomic integer containing the next thread ID to be assigned
private static final AtomicInteger nextId = new AtomicInteger(0);
// Thread local variable containing each thread's ID
private static final ThreadLocal<Integer> threadId =
new ThreadLocal<Integer>() {
#Override protected Integer initialValue() {
return nextId.getAndIncrement();
}
};
// Returns the current thread's unique ID, assigning it if necessary
public static int get() {
return threadId.get();
}
}

Categories

Resources