synchronized lock and separate threads: Android - java

I have a callback function in which i receive a string.
This string is to be passed to a separate thread for processing since the processing takes time.
Also, since multiple callbacks can come simultaneously, I would like to have a synchronized lock till i pass the string into the new thread. But I do not wish to have the new thread (where processing is going on) to be locked also.
Could someone please help me figure out the design for this?
I have written the following code but in this I think in this no callbacks can be received till the whole processing of the separate thread is also done, thereby defeating the whole purpose of this new thread.
String sLine;
onClick(String line){
synchronized (lock) {
sLine = line;
new Thread(new Runnable() {
#Override
public void run() {
doProcessing(Sline);
}).start();
}
}

Also, since multiple callbacks can come simultaneously, I would like to have a synchronized lock till i pass the string into the new thread.
A: I don't think you need to put a lock here. This string is not accessed by multi-thread.
But I do not wish to have the new thread (where processing is going on) to be locked also.
A: As I see nothing was locked here :) I think it could be better if you do something like that:
Create an class Runner implement Runnable, this class will do processing
Everytime you got callback, use ThreadPoolExecutor to execute this Runner. This help you reuse Thread instance.
Note that: These line code doesn't need to synchronized, put synchronized inside processing method if you need.
// Implement class Runner
public class Runner implements Runnable {
private String mLine;
public Runner(String line) {
mLine = line;
}
#Override
public void run() {
process();
}
public void process() {
// Do processing with mLine
// Put synchronized if you need, it bases on your context
}
}
// Initialize thread pool
private ThreadPoolExecutor executor = new ThreadPoolExecutor(10, 100, 1000, TimeUnit.SECONDS, new LinkedBlockingDeque<Runnable>());
// Execute runner when receiving callback
onClick(String s) {
Runner runner = new Runner(s);
executor.execute(runner);
}

Try changing like below
String sLine;
onClick(final String line){
sLine = line;
new Thread(new Runnable() {
#Override
public void run() {
doProcessing(line);
}).start();
}

Related

How can I combine the results of multiple threads?

I am trying to perform a replace operation on the same string with multiple threads. I have created a class that will do so, given the text and a list of string arrays containing the targets and replacements:
public class ParallelReplacer implements Runnable {
private String text = "";
private List<String[]> targetsAndReplacements = null;
public ParallelReplacer(String text, List<String[]> targetsAndReplacements) {
this.text = text;
this.targetsAndReplacements = targetsAndReplacements;
run();
}
public void run() {
for(String[] s : this.targetsAndReplacements) {
this.text = performReplace(text, s);
}
}
private String performReplace(String text, String[] targetAndReplacement) {
text = text.replace(targetAndReplacement[0], targetAndReplacement[1]);
return text;
}
}
I execute it like so:
List<String[]> targetsAndReplacements = new ArrayList<String[]>();
targetsAndReplacements.add(new String[] {"a", ""});
targetsAndReplacements.add(new String[] {"e", ""});
targetsAndReplacements.add(new String[] {"i", ""});
targetsAndReplacements.add(new String[] {"o", ""});
targetsAndReplacements.add(new String[] {"u", ""});
String text = "I am trying to perform a replace operation the same string with multiple threads.";
text = new ParallelReplacer(text, targetsAndReplacements.subList(0, targetsAndReplacements.size() / 2)).getResults();
text = new ParallelReplacer(text, targetsAndReplacements.subList(targetsAndReplacements.size() / 2, targetsAndReplacements.size())).getResults();
However, the second thread only executes after the first thread has finished, defeating the purpose of haveing multiple threads. How can I have the two threads executing simultaneously, and then merge the results after they are done?
All your program is in the same thread
A Runnable it's a interface that need to be passed as argument of a thread
You need to execute the ParallelReplacer's instances in new threads
The question that maybe you gonna have, is how get the result, so, you want to use a callback to this, when the execution of the thread is done, the callback is called
public interface IMyCallback {
public void onSucess(String result);
public void onError();
}
Do this in ParallelReplacer
public class ParallelReplacer implements Runnable {
//...
IMyCallback myCallback;
public ParallelReplacer(String text, List<String[]> targetsAndReplacements, IMyCallback myCallback)
{
this.myCallback = myCallback;
this.text = text;
this.targetsAndReplacements = targetsAndReplacements;
run();
}
public void run() {
for(String[] s : this.targetsAndReplacements) {
this.text = performReplace(text, s);
}
myCallback.sucess(text);
}
}
Declare this out of the next method:
int finishedThreads = 0;
ArrayList<String> resultsThreads = new ArrayList<String>();
Do this:
public void callMeWhenAThreadFinished(String result){
finishedThreads++;
resultsThreads.add(result);
if(finishedThreads==2){
//do what you want to do with the results
}
}
and this:
//...
Runnable r1 = new ParallelReplacer(someText, targetsAndReplacements.subList(0, targetsAndReplacements.size() / 2),new IMyCallback() {
#Override
public void onSucess(String result) {
callMeWhenAThreadFinished(result);
}
#Override
public void onError() {
}
});
new Thread(r1).start(); //You forgot this
Runnable r2 = new ParallelReplacer(someText, targetsAndReplacements.subList(targetsAndReplacements.size() / 2, targetsAndReplacements.size()),new IMyCallback() {
#Override
public void onSucess(String result) {
callMeWhenAThreadFinished(result);
}
#Override
public void onError() {
}
});
new Thread(r2).start();
Hugs
While this may be helpful for starting to learn about multithreading, it's not useful for string processing. As stated in the comments, it's not gonna be conducive to merging the string later (at least in its current form).
The answer to your question is that Runnable provides a way to run functionality in a separate thread. But it doesn't provide the background thread itself.
In order to have it work in separate threads, you'd need to do something like this:
Thread first = new Thread(new ParallelReplacer(text, tars.subList(0, tars.size() / 2)));
Thread second = new Thread(new ParallelReplacer(text, tars.subList(tars.size() / 2, tars.size())));
Then you need to use the Thread.join API to wait for completion of the background threads in order to get the results. Or Object.notify in the threaded code, with Object.wait in the code that needs it.
I'm guessing that this is a homework question, so I won't go further here. But please do note that writing multithreaded code is nontrivial, and hard to get right even for very experienced developers. If this isn't just homework, you'll do far better using a proven library to help accomplish your work.
the fundamental problem with your code is that it never uses any threads.
a Runnable in java is just a class that's garunteed to have a void method run that takes no arguments, so you're just calling it as you would any other function
Starting the Threads
to use threading, java has it's own class, Thread,
where thread is expecting a class that implements runnable, so you can do
ParallelReplacer[] replacers=new ParallelReplacer[{number of threads}];
Thread[] threads=new Thread[{number of threads}];
for(int i=0;i<threads.length;i++){
replacers[i]=new ParallelReplacer(...);
threads[i]=new Thread(replacers[i]);
}
this makes an array of Thread objects, ready to go with the replacer they're supposed to run, but it doesn't start them yet. To spawn the thread you call .start() on that thread, beginning it's execution, separately from the main thread, which continues running.
so you would do
for(int i=0;i<threads.length;i++){
thread[i].start();
}
or just start each one after you create it in the previous loop
Output
the main thread of execution runs separately, and will run the next couple of commands before the ones you spawned finish execution, (even if the next command is return!), so you need to at some point tell your main to wait for all the spawned threads to finish
you can do this by calling join() on each spawned thread
for(int i=0;i<threads.length;i++){
threads[i].join();
}
what join does is it tells the currently executing thread (ie main in this case) to wait until the thread it's called on to finish. because of this, it has to be done in a separate loop, other wise you would just have
start thread 1,
stop thread 1
start thread 2
...
and might as well not use threads at all
after all the threads are joined, you can loop through the replacers array, and append all the results.
however
you can do better! all the threads share the same heap, which is where java allocates it's objects. if you change your input string (which is immutable) to a StringBuilder (which can be changed in place), then you could have each thread change it's section, and when they are all joined, the StringBuilder would be all replaced.

Not entering thread method

i am writing code from online to create a chat application. After trouble shooting my program to find out why it is not working I have discovered that the code inside my run method here is not being reached. here is the snippet of code
public void listen()
{
listen = new Thread("Listen") {
public void run()
{
writeMessage("Working in here");
while (true) {
String message = client.receive();
if (message.startsWith("/c/")) {
client.setID(Integer.parseInt(message.substring(3, message.length())));
writeMessage("Successfully connected to server" + client.getID());
}
}
}
};
}
It is reaching the listen method itself, because if i use the write message command before i declare the thread, it prints out the message for me, any idea from looking at this why it will not enter any further?
Thanks
Calling start() on your Thread would do it:
public void listen()
{
listen = new Thread("Listen") {
public void run()
{
writeMessage("Working in here");
while (true) {
String message = client.receive();
if (message.startsWith("/c/")) {
client.setID(Integer.parseInt(message.substring(3, message.length())));
writeMessage("Successfully connected to server" + client.getID());
}
}
}
};
listen.start(); // <-- Add this line
}
Also, you typically don't want to extend Thread (which you are doing here with an anonymous class). Usually you'll want to create a Runnable and pass that to Thread's constructor instead:
Runnable r = new Runnable() {
#Override
public void run()
{
// Do some work here
}
};
Thread listen = new Thread(r, "Listen");
listen.start();
Or even better, use an Executor, there aren't many good reasons to create your own Thread objects.
Certainly working with appropriate Execotor or even better ExecutorService is more appropriate way of working with threads today. Read about it here. But if you insist on working the old way then you need to invoke start() method of your thread. Methods start() and run() do the same thing, only run() execute your thread sequentially i.e. in the same thread where you invoked it and start() actually starts a new thread where your code is executed which is what you wanted in the first place

How to run a Listener in a different thread or do its calculation in a different thread

I'm trying to build a cache with Google Guava and want to do some calculation on the expired objects. A removalListener notifies me, if some object was removed.
How can I run the removalListener in a different thread than the main application or pass the expired object (in the simple example below, that would be the Integer 3) to a different thread that handles the calculation?
Edit: As the calculation is rather short, but happens often, I would rather not create a new thread each time (would be thousands of threads), but have one (or maybe two) who calculate all objects.
Simple example:
Cache<String, Integer> cache = CacheBuilder.newBuilder().maximumSize(100)
.expireAfterAccess(100, TimeUnit.NANOSECONDS)
.removalListener(new RemovalListener<String, Integer>() {
public void onRemoval(final RemovalNotification notification) {
if (notification.getCause() == RemovalCause.EXPIRED) {
System.out.println("removed " + notification.getValue());
// do calculation=> this should be in another thread
}
}
})
.build();
cache.put("test1", 3);
cache.cleanUp();
To run your listener in an executor, wrap it with RemovalListeners.asynchronous.
.removalListener(asynchronous(new RemovalListener() { ... }, executor))
Create an ExecutorService using one of the Executors factory methods, and submit a new Runnable to this executor each time you need to:
private ExecutorService executor = Executors.newSingleThreadExecutor();
...
public void onRemoval(final RemovalNotification notification) {
if (notification.getCause() == RemovalCause.EXPIRED) {
System.out.println("removed " + notification.getValue());
submitCalculation(notification.getValue());
}
}
private void submitCalculation(final Integer value) {
Runnable task = new Runnable() {
#Override
public void run() {
// call your calculation here
}
};
executor.submit(task);
}
You can create a new class, and implement the java.utils.Runnable interface like so;
public class MyWorkerThread implements Runnable {
public MyWorkerThread(/*params*/) {
//set your instance variables here
//then start the thread
(new Thread(this)).start();
}
public void run() {
//do useful things
}
}
When you create a new MyWorkerThread by calling the constructor, execution is returned to the calling code as soon as the constructor is finished, and a separate thread is started that runs the code inside the run() method.
If you might want to create MyWorkerThread objects without immediately starting them off, you can remove the Thread.start() code from the constructor, and call the thread manually from the instance later like so;
MyWorkerThread t = new MyWorkerThread();
//later
(new Thread(t)).start();
Or if you want to keep a reference to the Thread object so you can do groovy things like interrupt and join, do it like so;
Thread myThread = new Thread(t);
myThread.start();
//some other time
myThread.interrupt();
you can simply create intermediate queue for expired entities (expiration listener will just add expired object to this queue) - say some sort of blocking in-memory queue - ArrayBlockingQueue, LinkedBlockingDeque.
Then you can setup thread-pool and handlers(with configurable size) that will consume objects using poll() method.
For high-performance queue - i can advice more advanced non-blocking queue implementation if needed. also you can read more about high-performance non-blocking queues here Add the first element to a ConcurrentLinkedQueue atomically
Use an executor service to dispatch your task to a different thread.
ExecutorService have an internal blocking queue that is used for safe publishing of references between the producer and the consumer threads. The factory class Executors can be used to create different ExecutorService with different thread management strategies.
private ExecutorService cleanupExecutor = Executors.newFixedThreadPool(CLEANUP_THREADPOOL_SIZE);
...
public void onRemoval(final RemovalNotification notification) {
if (notification.getCause() == RemovalCause.EXPIRED) {
System.out.println("removed " + notification.getValue());
doAsyncCalculation(notification.getValue());
}
}
private void doAsyncCalculation(final Object obj) {
cleanupExecutor.submit(new Runnable() {
public void run() {
expensiveOperation(obj);
}
}
}
In doAsyncCalculation you are creating new tasks to be run but not new threads. The executor service takes care of dispatching the task to the threads in the executorService's associated thread pool.

Invoking different methods within one runnable thread in java

As far as my understanding is so far; a class which implements runnable seems to only be able to perform one set task within its run method. How is it possible to create a new thread and then run different methods from this one additional thread, without needing to create some new runnable class for every set task.
Make your own subclass of Thread (MyThread extends Thread)
Add private members to control the behavior.
Add bean-pattern get/set methods to control the private members, or use a fluent API.
Read this properties in the run() method.
MyThread t = new MyThread();
t.setTypeOfSparrow("African");
t.setFavoriteColor("Yellow");
t.start();
Your Runnable class can call any logic it likes. The logic you want to run must be in some class, could be different methods of the Runnable class or could be in lots of other classes.
How did you plan to tell the runnable what to do?
You could do something like:
MyRunnable implements Runnable {
private String m_whatToDo;
public MyRunnable(String whatToDo) {
m_whatToDo = whatToDo;
}
public void Runnable run() {
if ("x".equals(m_whatToDo) {
// code to do X
} else if ( "y".equals(m_whatToDo) {
// code to do Y
} else {
// some error handling
}
}
}
Or as Srikanth says you could communicate the intent by other means such as thread names.
However I don't see much overhead in creating a runnable class. Just adding a public void run() to a class is surely not that big a deal?
A class should perform one task and perform it well, and if you are adding multiple operations in a single Runnable then you are violating this principle. You should create a new implementation of Runnable for each runnable task.
To simplify your api you might like to create a MyRunnableFactory method which constructs a runnable class depending on one or more construction criteria. This would shield the user from having to remember which class to create for each task.
Your question isn't quite clear. My guess is that you want to run different methods in some other thread, but you don't want to waste time restarting a new thread for each method. In that case you need an ExecutorService with one thread. You can submit sequentially some Runnables to a thread that is kept alive between calls.
Or more simply if you already know the order in which your methods are called
(new Thread() {
#Override public void run() {
method1();
method2();
...
}
}).start();
In the run() method check for the thread name and call the appropriate method.
public class SampleThread implements Runnable{
/**
* #param args
*/
Thread t=null;
public SampleThread(String threadName)
{
t=new Thread(this,threadName);
t.start();
}
#Override
public void run() {
if(t.getName().equals("one"))
{
One();
}
else if(t.getName().equals("two"))
{
Two();
}
}
public void One()
{
System.out.println(" ---- One ---- ");
}
public void Two()
{
System.out.println(" ---- Two ---- ");
}
public static void main(String[] args) {
SampleThread t1=new SampleThread("one");
SampleThread t2=new SampleThread("two");
}
}

how to override thread.start() method in java?

I need to implement thread.start() method in my java code. Please let me know through an example of overriding of thread.start() method and how it works?
You should not. Override run instead
You can override start as any other method
Thread myThread = new Thread() {
#Override
public void start() {
// do something in the actual (old) thread
super.start();
}
#Override
public void run() {
// do something in a new thread if 'called' by super.start()
}
};
but you must call super.start() to create a new thread and have run() called in that new thread. The original start does some magic (native code) that you hardly can mimic.
If you call run() directly from within your start() (or any other method), it is executed in the actual thread as a normal method, not in a new thread. There is no reason to use a Thread if you don't want to run some code in a new thread.
You must put your decision logic in the run() method, maybe using some variable set in the constructor (or another method, eventually in start) if that is really needed. I can not find any reason for needing this variable, it should be enough to test the condition in run() as already suggested elsewhere.
class MyThread extends Thread {
private final boolean flag;
public MyThread(boolean someCondition) {
flag = someCondition;
}
// alternative
// #Override
// public synchronized void start() {
// flag = <<someCondition>>
// super.start();
// }
#Override
public void run() {
if (flag) {
// do something like super.run()
} else {
// do something else
}
}
}
but it would be easier to understand and maintain if you do it like #Henning suggested!
It's also a more object oriented solution...
As others said, overriding Thread.start() is not the way to do it. Usually, I wouldn't override Thread.run() either, but use a Runnable.
If you have to decide which method to run after the thread has been spawned, you could do something like this:
final Runnable runnableA = ...;
final Runnable runnableB = ...;
Runnable r = new Runnable() {
#Override
public void run() {
if (...) {
runnableA.run();
} else {
runnableB.run();
}
}
}
Thread thread = new Thread(r);
thread.start();
If, as you say, you have a superclass and a subclass where the run() method is overidden, you can just rely on late binding and the proper method will be invoked automatically:
Runnable couldBeAOrB = ...;
Thread thread = new Thread(couldBeAOrB);
thread.start();
You don't override the start, you override the "run". You can simply implement a thread by:
new Thread() {
public void run() {
//your code here
}
}.start();
//start will call the logic in your run method
Actually, you can call run() to run a thread instead of start() to run a thread. But there is a little difference.
Suppose you create two threads:
Thread t1 = new Thread();
Thread t2 = new Thread();
Case 1 : If you call "t1.run()" and "t2.run()" one after another they will start to run t1 and t2 synchronously (sequentially).
Case 2 : If you call "t1.start()" and "t2.start()" one after another they will call their run() methods and start to run t1 and t2 asynchronously (in parallel).
Agree with Schildmeijer, don't override start, override run() instead.
In fact, although start can be overridden (it's not final), it calls the native start0 method which in turn will cause the VM to call the run method (actually from the context of a native thread/process). The native start0 method has private access, so even if you overrode the start, I can't see how you could reproduce the affect.
The client calling start() is within a thread (lets say, the main thread), it's not until the run method has done its thing that another thread will be spawned.
Take a look at the Sun (ahem, Oracle) tutorial on threads at http://download.oracle.com/javase/tutorial/essential/concurrency/index.html, in particular the section on starting threads.
class Worker implements Runnable{
public void run(){
if("foo"){
runFoo();
} else {
runBar();
} }
private void runFoo(){
// something }
private void runBar(){
// else }
}
I'm pretty sure, you needn't to overwrite the start-Method.
By the way: Take al look at java.util.concurrent.Callable
http://download.oracle.com/javase/1.5.0/docs/api/java/util/concurrent/Callable.html
It is discouraged to override Thread, if possible create an implementation of the Runnable interface instead and run that on a thread. This can also be done with a lambda expression, making everythin super short and simple.
// create a new thread and give it a Runnable with a lambda expression and a custom name
Thread thread = new Thread(() -> {
// put your code here
}, "CustomThreadName");
// start it
thread.start();
If we provide our own implementation of start method then it will work like a normal method call and will work on the current thread stack only. New thread will not be created.
Yes the start() method can be overridden. But it should not be overridden as it is implementation in thread class has the code to create a new executable thread and is specialised.
We can override start/run method of Thread class because it is not final. But it is not recommended to override start() method
class Bishal extends Thread {
public void start()
{
System.out.println("Start Method");
}
public void run()
{
System.out.println("Run Method");
}
} class Main{
public static void main(String[] args)
{
Bishal thread = new Bishal();
thread.start();
System.out.println("Main Method");
}
}
when we are calling start() method by an object of Bishal class, then any thread won’t be created and all the functions are done by main thread only.

Categories