How to share a variable between two sub classes that implements runnable - java

I have a main class and two subclasses, subClass1 and subClass2 that implements runnable...
I have run the two threads simultaneously
by calling
t1.start // t1 for subclass1
t2.start // t2 for subclass2
Now, I want t1 to run till the t2 completes.
I can add a boolean flag within the method in subclass2 to recognize that the execution has been completed;
Now I need to pass that information(boolean variable) to subclass1 to stop the execution of a set of codes from within it. [have used while(true) loop;]
so how can i create a common variable that can be accessed by both sub classes?
Can anybody please suggest me a solution for this?

Pass an AtomicBoolean to the subclasses.
public class SubClass1 implements Runnable {
private AtomicBoolean b;
public SubClass1(AtomicBoolean b) {
this.b = b;
}
public void run() {
while(b.get()) { // Assuming SubClass2 sets it to false when it's no longer running
// Do something
}
}
}
Implementing SubClass2 is left as an exercise to the OP.

If possible I'd recommend to avoid sharing mutable state in concurrent environment, but assuming you have one of those cases where it cannot be avoided you can try something like (adjust for your own needs):
class SharedState {
public final Object mutex = new Object();
public boolean variable;
}
class Subclass extends MyClass1 implements Runnable {
private SharedState sharedState;
public Subclass1(SharedState sharedState) {
this.sharedState = sharedState;
}
// ...
#Override
public void run() {
// ...
synchronized(sharedState.mutex) {
// access sharedState.variable
}
// ...
}
}
Basically create SharedState outside and inject into your subclasses on creation (or create it within one of them, retrieve and inject into another, whatever). Then use that shared variable remembering all you know about trickiness of shared state.

Related

how the instanceof usage can be avoided?

How can we avoid using instanceof operator for writing a clean code
say for example:
If an object is of Type1 do something, but if it is of Type2 then do something else.
if(obj instanceof T1){
doSomething()
}else(obj instanceof T2){
doOtherThing()
}
Generally you use a series of instanceof with a cast to invoke a specific method that exists in a class but not in others :
if(obj instanceof T1){
((T1)obj) doSomething();
}
else(obj instanceof T2){
((T2)obj) doOtherThing();
}
To avoid that, if you can modify these classes, T1 and T2 should be subclasses of a common base class and the invoked method should be defined in the base class.
In this way, each subclass may implement it and you could so write :
obj.doSomething();
if you cannot modify these classes, you can always introduce an Adapter class that wraps them to provide a common way to invoke these methods.
Adapter
public interface Adapter{
void process();
}
AdapterForT1
public class AdapterForT1 implements MyAdapter{
private T1 adapted;
public AdapterForT1(T1 adapted){
this.adapted = adapted;
}
public void process(){
adapted.doSomething();
}
}
AdapterForT2
public class AdapterForT2 implements MyAdapter{
private T2 adapted;
public AdapterForT2(T2 adapted){
this.adapted = adapted;
}
public void process(){
adapted.doOtherThing();
}
}
And you may use them in this way :
MyAdapter adapter = new AdapterForT1(obj);
...
adapter.process();
or :
MyAdapter adapter = new AdapterForT2(obj);
...
adapter.process();
You need to use method overriding here and then call the same function from different instances of different classes which will execute a different set of instructions as per implemented in individual classes
So for instance, you have a class T and then class T1 and class T2 both extends class T and all three classes implement executeTask function
So,
T t1 = new T1();
T t2 = new T2();
// this will execute function overridden in T1
t1.executeTask();
// this will execute function overridden in T2
t2.executeTask();
Create an interface, which both classes implement. An interface is sort of a contract that every implementing class has to comply with.
With this you can ensure that every instance of such a class has all defined methods from that interface implemented.
For example:
public interface CustomExecutable {
void execute();
}
Then your two classes:
public class T1 implements CustomExecutable {
#Override
public void execute() {
// Do t1 logic
}
}
public class T2 implements CustomExecutable {
#Override
public void execute() {
// Do t2 logic
}
}
In your main program you could do something like this:
CustomExecutable ce = new T1();
ce.execute(); // Does t1 logic
ce = new T2();
ce.execute(); // Does t2 logic
instanceof isn't necessary anymore, because each type has its own way of executeing its code.

Java singleton enum programmed to the interface?

This is my first post on here so I will try to be precise. This is for a university project, we have to create a fish tank simulation on top of an OO architecture that we individually make. I'm exploring the uses of singletons and have found them quite useful, however reading online the way I currently implement it is not thread safe.
The way I currently implement it (Think its the lazy method) Note: We have to go through the interface
public interface myInterface
{
void foo();
}
public class myClass implements myInterface
{
private static myInterface instance;
private myClass(){}
private static myInterface Instance()
{
if(instance == null)
instance = new myClass();
return instance;
}
public void foo()
{
//Do stuff
}
public void bar()
{
//Do More Stuff
}
}
This works well however its not thread safe I could add the synchronized keyword to the getter but I've read that that is quite heavy on the system and I have quite a few singletons.
private synchronized static myInterface Instance()
{
if(instance == null)
instance = new myClass();
return instance;
}
I have then moved on to an enum singleton which is thread safe and is not heavy on the system however I am unsure on how to program it to the interface.
public enum myClass implements myInterface
{
INSTANCE;
private myClass(){}
public void foo()
{
//Do stuff
}
public void bar()
{
//Do More Stuff
}
}
In programming to the interface I mean when I call the singleton I can only access methods that are in the interface (please correct me if I'm referring to this wrongly). This is where the way I have done the enum singleton fails. For example: With the lazy singleton I can not call this as its not in the interface:
myClass.Instance().bar();
But it can call this which is correct, as it is in the interface.
myClass.Instance().foo();
With the enum however I can call this and its not programming to the interface
myClass.INSTANCE.bar();
I understand why its doing this as the class is an enum so it will be able to call everything in that enum class. So after this long post which I apologise for, the main question is: Can I make the enum version only call methods that are declared in the interface?
If it can't how heavy is a synchronized method on the system, I would have around 4-6 of them?
Please Note: Even though this is for a university project we are only running the simulation on one thread so it does not even need to be thread safe. I don't quite understand multi-threading but I thought it would be a good learning opportunity.
You can always hide your enum implementation as well if you prefer the enum route:
public interface Singleton {
void foo();
}
public final class SingletonAccessor {
public static Singleton getInstance() {
return SingletonImpl.INSTANCE;
}
private SingletonAccessor() {
}
private enum SingletonImpl implements Singleton {
INSTANCE;
public void foo() {
// ...
}
public void bar() {
// ...
}
}
}
EDIT
As pointed out by Peter Lawrey in the comments, you can even use an enum for the SingletonAccessor :)
public enum SingletonAccessor {
SINGLETON;
public Singleton get() {
return SingletonImpl.INSTANCE;
}
private enum SingletonImpl implements Singleton {
INSTANCE;
public void foo() {
// ...
}
public void bar() {
// ...
}
}
}
You can cast it to the interface or
myInterface my = myClass.INSTANCE;
my.foo();
You can still use a method like
myClass.getInstance().foo();
But this isn't a real solution IMHO.
Can I make the enum version only call methods that are declared in the interface?
Ultimately you have to decide which methods you want on the instance which are public. If you make a method or field public, you can access it and if you don't want to be able to access it, make it private.
At some point you have to trust you know what you are doing and you do things for a reason. You don't have to think up ways to prevent yourself from call code you wrote.
just simply change your singleton class this way:
public class myClass implements myInterface
{
private static myInterface instance = new myClass();
private myClass(){}
private static myInterface Instance()
{
return instance;
}
public void foo()
{
//Do stuff
}
public void bar()
{
//Do More Stuff
}
}
this will assure that the singleton object will be created at class-loading time, and you don't need to worry about race-conditions in the Instance() method
Try looking at java.util.concurrent.atomic.AtomicReference. Specifically compareAndSet.
instance.compareAndSet(null, new MyClass());
That is if your instance field is null, set to new object, if not null, leave intact. Should be less heavy.

Unable to access global variables via Runnable in class

Good Day,
I have a class called FunctionHandler, that contains a method called evaluate like this:
class FunctionHandler{
Object globalVar;
public void Evaluate(){
ThreadPool pool;
Runnable task = new Runnable(){
public void run() { aWorkerTask(globalVar); }
}
pool.start(task);
pool.stop();
}
public void aWorkerTask(Object object){//worker stuff}
}
The problem is, my Runnable object can't seem to access globalVar! It seems to be it's own object somehow that can't reference what is inside it's class. Is there anyway around it?
The problem is that this code inherently doesnt work. Runnable cannot access globaVar. I need aWorkerTask to be wrapped in a Runnable and it needs access to globalVar
I'm not sure if this is the best implementation, but what I did was to create a class that implements Runnable as such:
public class MyRunnable implements Runnable {
private FunctionHandler functionHandler; //Global Reference - Only reading from it
private Object globalVar;
public MyRunnable(FunctionsHandler functionsHandler,Object globalVar) {
this.functionsHandler = functionsHandler;
this.globalVar = globalVar;
}
public void run(){
functionHandler.aWorkerTask(globalVar)
}
}
And pass in the main object functionHandler, which contains the function I need to make as a Runnable.
I then create a runnable as such:
MyRunnable taskProcessor = new MyRunnable(this,variableName,functionValues,jobNum.toString());
threadPool.runTask(taskProcessor);
A Runnable object is indeed its own object. Your options are to set it via a mutator or declare globalVar as final. Here's the mutator solution, in case you don't want globalVar to be final:
public void startRun() {
Object globalVar = new Object();
Runnable run = new Runnable() {
Object localVar;
public Runnable prepare(Object param) {
localVar = param;
return this;
}
#Override
public void run() {
/* Do your stuff */
}
}.prepare(globalVar);
}
Note that if you do this and you want globalVar to be modifiable both inside and outside the thread, you'll need to wrap it in a suitable dereferencing object.
If you want runnables to be able to access class variables, they have to be static; just change your code to:
static Object globalVar;

How do I access a class's variables from a class that I created within that class?

I have two classes as such:
public class A{
ArrayList<Runnable> classBList = new ArrayList<Runnable>();
int x = 0;
public A(){
//This code here is in a loop so it gets called a variable number of times
classBList.add(new B());
new Thread(classBList.get(classBList.size())).start();
}
}
public class B implements Runnable{
public B(){
}
public void run(){
//Does some things here. blah blah blah...
x++;
}
}
The problem is that I need to have the instance of class B change the variable x in class A, the class that created class B. However, I do not know how I would let class B know that it needs to change the value or if it can. Any suggestions on how to change it would be greatly appreciated. Thank you!
You need to give your B instance access to the A instance. There are a couple of ways to do that:
Make B derive from A and make the data fields (or accessors for them) protected in A. I would tend to shy away from this one.
Make B accept an A instance in its constructor.
Make B accept an instance of a class that implements some interface in its constructor, and have A implement that interface.
Which you choose is up to you. I've given them in roughly decreasing order of coupling, where the more loosely-coupled, the better (usually).
That third option in code:
public TheInterface {
void changeState();
}
public class A implements TheInterface {
ArrayList<Runnable> classBList = new ArrayList<Runnable>();
int x = 0;
public A(){
//This code here is in a loop so it gets called a variable number of times
classBList.add(new B(this)); // <=== Passing in `this` so `B` instance has access to it
new Thread(classBList.get(classBList.size())).start();
}
// Implement the interface
public void changeState() {
// ...the state change here, for instance:
x++;
}
}
public class B implements Runnable{
private TheInterface thing;
public B(TheInterface theThing){
thing = theThing;
}
public void run(){
// Change the thing's state
thing.changeState();
}
}
Now, both A and B are coupled to TheInterface, but only A is coupled to B; B is not coupled to A.
You need to extend Class A within Class B, i.e.:
public class B extends A implements Runnable {
}
This sets Class B up as a subclass of Class A and allows it to access its variables.
You need do make the class B somehow know about which instance of class A created it.
It can have a reference to its creator for example:
public class B implements Runnable{
private A creator;
public B(A a){
creator = a;
}
public void run(){
//Does some things here. blah blah blah...
x++;
}
}
and then pass the creator when you construct it from the class A:
...
classBList.add(new B(this));
...

synchronized method instead of synchronized statement in java

I have a method with a synchronization statement on an "non-this" object
class Some_Class {
public A s = new A();
public void method_A() {
synchronized(s) {
....
}
}
}
Can I instead extend class A and synchronize as follows:
class B extends A {
public A a;
public B(A a) {
this.a = a;
}
public synchronized void some_m() {
...
}
}
class Some_Class {
public A s = new A();
public void method_A() {
B b = new B(s);
b.some_m();
}
}
Are these two synchronizations equivalent?
No, they're not equivalent. This method here:
public synchronized void some_m() {
...
}
Does the same as this one:
public void some_m() {
synchronized(this) {
...
}
}
Or in other words
Your first code option synchronises on an instance of A in Some_Class (a class member, visible to everyone).
Your second code option synchronises on the instance of B within Some_Class.method_A() (a local variable, invisible to the outside of that method)
No, they are not equivalent. In second case you actually don't have synchronization at all. Because some_m method synchronized on instance of B. So you create local instance of B and call method on it. This method is synchronized only on this local instance of B and other threads don't care about it and can do whatever they want with s because it's not synchronized.
Can you describe what you want to achieve?
Synchronized block synchronizes the whole object while synchronized method synchronizes just that method. In the second case, some thread can still access other non-synchronized methods of the object.

Categories