Cant call a void method in a class in java - java

I'm trying to call a method in another class, however, I'm getting an error. I initialize the class to a variable, but I do not get the option to call that method. not even the variable shows up in the auto-complete when I start typing.
this is the class I'm calling:
public class aMessageBuffer {
private Collection<Message> messageBuffer = new ArrayList<Message>();
private Collection<Integer> responseBuffer = new ArrayList<Integer>();
private boolean messageBufferFull = false;
private boolean responseBufferFull = false;
//Called by aProducerTask
public void sendMsg(String op, int val){
//place message in messageBuffer
Message msg = new Message();
msg.setValues(op,val);
messageBuffer.add(msg);
messageBufferFull = true;
//todo: notify
while (responseBufferFull == false){
//wait...
}
//remove response from responseBuffer
responseBuffer.clear();
responseBufferFull = false;
//todo: Out Response
}
}
and this is where I'm calling it from:
public class aProducerTask extends Thread {
//TODO: Send Messages
private aMessageBuffer msgbuf = new aMessageBuffer();
msgbuf.sendMsg("add",3);
//TODO: Print Results
}
I'm getting the error in the msgbuf.sendMsg("add",3);
it is not allowing me to call the method with that variable
This is my Main:
public class Main{
public static void main(String args[]){
new aConsumerTask().start();
new aProducerTask().start();
}
public void run() {
}
}

You should define run method in your class aProducerTask.
public class aProducerTask extends Thread {
//TODO: Send Messages
private aMessageBuffer msgbuf = new aMessageBuffer();
public void run() {
msgbuf.send("add",3);
}
//TODO: Print Results
}

Don't call non-assignment methods naked in the class and outside of any method, constructor or similar block.
Here you'll want to call the non-assignment method in the run method.
Don't extend Thread, implement Runnable and give it a run method which will hold your method call. Then create a new Thread when needed, pass in the Runnable and call start() on the Thread.
You will want to learn and use Java naming conventions. Variable names should all begin with a lower letter while class names with an upper case letter. Learning this and following this will allow us to better understand your code, and would allow you to better understand the code of others.
In the future if you have similar questions about a compilation error, post the full error message with your question, and please proof-read your code for correctness. 90% of our comments to questions are about clarification and correction.
So not:
public class aProducerTask extends Thread {
//TODO: Send Messages
private aMessageBuffer msgbuf = new aMessageBuffer();
msgbuf.sendMsg("add",3);
//TODO: Print Results
}
but rather this:
// improve class name and have it implement Runnable
public class AProducerTask implements Runnable {
private aMessageBuffer msgbuf = new aMessageBuffer();
#Override // don't forget this!
public void run() {
msgbuf.sendMsg("add",3);
}
}
Then to use:
public new Thread(new AProducerTask()).start();

Related

Async callback and listener

I have the following interfaces:
public interface NumberOfCellsListener {
public void numberOfCellsChanged(int patientId, int numOfCells);
}
public interface NumberOfCells {
public void register(NumberOfCellsListener listener);
public int numOfCells(int patientId);
}
public interface ProbabilityOfCancer {
//this may be a time consuming calculation
public double probability(int patientId, int numOfCells, bool gender, double weight);
}
This is the structure of my cancer probability calculator. My task is to implement this such that it can be called asynchronously due to the time consuming nature of the calculations. I am new to Java, can anyone please guide me on how to implement these interfaces? I am not sure about the structure i.e. what goes where. I am guessing I should get the new number of cells from the method numberOfCellsChanged in NumberOfCellsListener's implementation. But since it is a void method, I am not sure what to do.
An Interface method that does not return something usually has the function of changing the internal state, or of using some other means of output (for example to print something to the console, send something over a network, or save it to a database or file.).
As for the specific interfaces:
A Listener as in NumberOfCellsListener is meant to be installed ('registered') with an object that calls a listener's method, in case a specific event occures. In your case, based on the interface name, I would assume, that your method is called, when the number of cells of some object changes. So the question for you should be, what that information (at that point) requires you to do, and do that in the method.
A class implementing NumberOfCells is supposed to make true of the above statement. It has a register method, that should put the listener in some sort of collection (maybe a List - e.g. an ArrayList?) and then, when a certain event occures, invoke all the list's listener's numberOfCellsChanged-methods.
So an example implementation could be:
public class NumberOfCellsPrinter implements NumberOfCellsListener {
public void numberOfCellsChanged(int patientId, int numOfCells) {
System.out.println("The number of cells for parentId:" + parentId + " has changed to " + numOfCells + ".");
}
}
...
public class PetriDish implements NumberOfCells {
private ArrayList<NumberOfCellsListener> listeners = new ArrayList<>();
private int numOfCells = 0;
public void register(NumberOfCellsListener listener) {
if (listener != null && !listeners.contains(listener)) {
listeners.add(listener);
}
}
public int numOfCells(int patientId) {
for (NumberOfCellsListener listener : listeners) {
listener.numberOfCellsChanged(parentId, numOfCells);
}
return numOfCells;
}
}
While this example is totally meaningless, and will always produce 0 as numOfCells, it should demonstrate the idea of listeners.
It is very important, that you familiarize yourself with the risks and traps concerning parallelism, since this is a key factor of your objective.
Try the following to learn about async callbacks in Java. You can find more tutorials and explanations here
// Java program to illustrate Asynchronous callback
interface OnGeekEventListener {
// this can be any type of method
void onGeekEvent();
}
class B {
private OnGeekEventListener mListener; // listener field
// setting the listener
public void registerOnGeekEventListener(OnGeekEventListener mListener)
{
this.mListener = mListener;
}
// My Asynchronous task
public void doGeekStuff()
{
// An Async task always executes in new thread
new Thread(new Runnable() {
public void run()
{
// perform any operation
System.out.println("Performing operation in Asynchronous Task");
// check if listener is registered.
if (mListener != null) {
// invoke the callback method of class A
mListener.onGeekEvent();
}
}
}).start();
}
// Driver Program
public static void main(String[] args)
{
B obj = new B();
OnGeekEventListener mListener = new A();
obj.registerOnGeekEventListener(mListener);
obj.doGeekStuff();
}
}
class A implements OnGeekEventListener {
#Override
public void onGeekEvent()
{
System.out.println("Performing callback after Asynchronous Task");
// perform some routine operation
}
// some class A methods
}

Java multithreading - variable not updated

I'm having some troubles with a variable while in a multi-threaded environment.
I have 3 components/threads: Controller, Handler, ExternalAgent.
Controller hands off raw data to Handler. Handler spins off a new ExternalAgent thread for further processing. ExternalAgent comes back to Handler once it's done doing its thing and adds messages to a linked list for further processing by the Handler.
The problem is, the messages added by the ExternalAgent are not visible to some methods inside the Handler. Here's the Handler code:
public class InboundHandler implements InboundController.Handler {
private Thread receiver;
private volatile LinkedList<Message> bufferedMsgs = new LinkedList<Message>();
private volatile boolean isAlive = true;
private final static Logger logger = Logger.getLogger(Logger.GLOBAL_LOGGER_NAME);
public InboundHandler() {
receiver = new Thread(this,"receiver");
receiver.start();
}
#Override
public void run() {
while (isAlive) {
processBuffer();
}
}
#Override
public void process(String msg) {
Message packet = (Message) new Parser<Message>(Message.class,msg).getObject();
new ExternalAgent(this,packet).start();
}
public void processBuffer() {
logger.info("Processing buffersize .." + bufferedMsgs.size());
synchronized (bufferedMsgs) {
Iterator<Message> it = bufferedMsgs.iterator();
while (it.hasNext()) {
//PROCESSING
}
}
}
public void addMsgToBuffer(Message m) {
synchronized (bufferedMsgs) {
bufferedMsgs.addLast(m);
}
}
Controller talks to Handler through the process(msg) interface
ExternalAgent talks to the Handler through the addMsgToBuffer(msg) interface.
In the method processBuffer(), the LinkedList bufferedMsgs always shows empty although if I print it in the method addMsgToBuffer(), it gives me the expected contents. I have tried everything in my knowledge to understand why this is happening but I am unable to figure it out.

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);
}
}

Android thread sometimes doesn't start

So I'm having problems with my threads in an Android project. I have a ThreadStarter class, with a BuildScreen() function, which actually creates the layout for each activity. The only problem is, sometimes the threads just won't start, and I have no idea why. They work like 98% of the time though, but when they don't, the current activity will never get initalized, and the user has to restart the app, which is inconvenient.
Here is a snippet of my code:
public class ThreadStarter
{
public static void BuildScreen()
{
try
{
GlobalVariables.screenDrawer.onStart();
GlobalVariables.listInitaliser.onStart();
Logger.log("ThreadStarter.BuildScreen", "Threads started");
}
catch(IllegalThreadStateException e)
{
GlobalVariables.screenDrawer.StopThread();
GlobalVariables.listInitaliser.StopThread();
Logger.log("ThreadStarter.BuildScreen", "Threads stopped");
GlobalVariables.screenDrawer.onStart();
GlobalVariables.listInitaliser.onStart();
}
catch(Exception e)
{
Logger.Error("Couldn't stop or start the threads!");
Logger.Error("Exception () Message: " + e.getMessage());
}
}
}
The threads:
public class ListInitialiser extends Thread
{
private static ListInitialiser _thread;
public synchronized void run()
{
GlobalVariables.CurrentActivity.UpdateLists();
}
public void onStart()
{
_thread = new ListInitialiser();
_thread.start();
}
public void StopThread()
{
if (_thread != null)
{
_thread.interrupt();
_thread = null;
}
}
}
I won't insert the ScreenDrawer thread here, because it's pretty much the same, except it calls another function.
And this is how every activity is created (of course the contentView differs in each file):
#Override
public void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
getWindow().getAttributes().windowAnimations = R.style.Fade;
setContentView(R.layout.activity_fine_data_3);
GlobalVariables.CurrentActivity = this;
ThreadStarter.BuildScreen();
Logger.log("INFORMATION", "Person3DataActivity (Information 3/5)");
}
In the GlobalVariables section I have these variables:
public static ScreenDrawer screenDrawer = new ScreenDrawer();
public static ListInitialiser listInitaliser = new ListInitialiser();
If anyone has a solution or and idea, please share it with me.
Thanks in advance.
EDIT: Okay, so I took onof's (rather harsh but useful :)) advice, and refactored my code to use AsyncTask instead. It seems to be working pretty fine. I managed to implement it into my AbstractActivity class, which is the parent of every Activity I use, and now all I have to do is call BuildScreen() method in every onCreate method.
Thanks for the replies everyone.
try to add this to your class where u declared Global Variables
private static ListInitialiser instance;
public static synchronized ListInitialiser getInstance() {
if (instance == null)
instance = new ListInitialiser();
return instance;
}
Everytime you donot have to create new when u r taking static.I dont know but may be this can help
You can't rely on static variables as everything that is static (non final) in Android can be cleared any time the system need memory. So don't think static = storage.
You should instead instantiate the objects when you need them, like following:
public static ScreenDrawer getScreenDrawer() {
return new ScreenDrawer();
}
public static ListInitialiser getListInitialiser () {
return new ListInitialiser ();
}

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