How to deal with multiple threads in the same class?

Themes are often designed in two ways ( see java tutorials ): either by extending the Thread class, or by implementing the Runnable class. In any case, you need to specify what will work inside the stream.

I developed a class, an adapter to an online resource that retrieves various kinds of information. This class consists of methods such as getInformationOfTypeA () and getInformationOfTypeB (). Both contain code for connecting to online resources, so both of them must be streamed to avoid deadlocks.

The question is, how do I create this? I can do this as shown below, but then I can only implement one method:

public class OnlineResourceAdapter implements Runnable { public void run() { //get stuff from resource getInformationOfTypeA(); } public static void main(String args[]) { (new Thread(new OnlineResourceAdapter ())).start(); } public void getInformationOfTypeA(){ //get information of type A } public void getInformationOfTypeB(){ //get information of type B } } 

Another way would be to create separate classes for each method, but that seems unnatural to me.

Btw: I am developing my application in j2me

UPDATE:

Thanks to your answers, I think that is most suitable for use as methods of the following type:

What do you think about this:

 public class OnlineResourceAdapter{ public void getInformationOfTypeA(){ Thread t = new Thread(new Runnable() { public void run() { //do stuff here } }); t.start(); } public void getInformationOfTypeB(){ Thread t = new Thread(new Runnable() { public void run() { //do stuff here } }); t.start(); } } 

What do you think about this?

+6
java multithreading java-me
source share
6 answers

It seems to me that you should have two different classes: InformationOfTypeAFetcher and InformationOfTypeBFetcher , each of which should implement Runnable . Each of them may have a link to an instance of your OnlineResourceAdapter (or something similar), but if they do different things, they must be different classes.

+6
source share

Two anonymous inner classes, for example, Thorbjørn Ravn Andersen suggested dimly above work. Here is a sample code:

 public class OnlineResourceAdapter { public final Runnable typeA; public final Runnable typeB; public OnlineResourceAdapter() { typeA = new Runnable() { public void run() { OnlineResourceAdapter.this.getInformationOfTypeA(); } }; typeB = new Runnable() { public void run() { OnlineResourceAdapter.this.getInformationOfTypeB(); // one can use a non-final typed variable // to store, which then<1> } }; } public static void main(String args[]) { OnlineResourceAdapter x = new OnlineResourceAdapter(); new Thread(x.typeA).start(); // start A new Thread(x.typeB).start(); // start B // <1>can be accessed here. } public void getInformationOfTypeA(){ // get information of type A // return the data or directly store in OnlineResourceAdapter. } public void getInformationOfTypeB(){ //get information of type B } } 

Edit: Yes, you proposed method is a good way. You can even make methods static. You can use "OnlineResourceAdapter.this". to access other variables to store the results.

+4
source share

For each class, create an anonymous class based on Runnable. This will allow you to do what you need to do in the run () method.

+1
source share

I don’t understand why you don’t like the idea of ​​creating several classes, because Java does not support higher-order functions, and the algorithm is a variable part of your code.

But if you need a single implementation of OnlineResourceAdapter , you can use the strategy template and do something like this:

 public interface InformationGetter { public void getInformation(); } public class OnlineResourceAdapter implements Runnable { private final InformationGetter informationGetter; public OnlineResourceAdapter(InformationGetter i) { this.informationGetter = i; } public void run() { //get stuff from resource i.getInformation(); } } 

and then, of course, you will create as many InformationGetter implementations as you need.

Think about it, looking back at this approach, the OnlineResourceAdapter now adds nothing but the execution of the InformationGetter runnable. Therefore, if you have no good reason, I would say that it’s just an InformationGetter implement Runnable directly.

+1
source share

Many people have already suggested good methods for doing this using several classes. Since it seems to you that you prefer a method that does not require multiple classes, you can also consider using a constructor to provide information about which resource will be retrieved:

 public class OnlineResourceAdapter implements Runnable { private string resourceType; public OnlineResourceAdapter(string resourceType) { this.resourceType = resourceType; } public void run() { if (resourceType.equals("A") { getInformationOfTypeA(); } else { // etc.. } } public void getInformationOfTypeA(){ //get information of type A } public void getInformationOfTypeB(){ //get information of type B } } 

Using:

 (new Thread(new OnlineResourceAdapter("A"))).start(); 
+1
source share

Use anonymous classes of type Callable (which, unlike Runnable can return values) and execute them using Executor . If the logic for getting information A and information B is very similar, you can, of course, reorganize it and use one, parameterize the inner class Callables.

I'm not sure Callable and Executor are part of the J2ME specification. In standard Java, I would choose the Proxy approach anyway and encapsulate the external resource as an interface.

 public class AsyncMethodsTest { public class OnlineResourceAdapter { private final ExecutorService executor = Executors.newFixedThreadPool(2); public String getInformationOfTypeA() throws InterruptedException, ExecutionException, TimeoutException { Callable<String> callable = new Callable<String>() { @Override public String call() throws Exception { // Connect to external resource Thread.sleep(500); return "A"; } }; Future<String> submit = executor.submit(callable); return submit.get(1000, TimeUnit.MILLISECONDS); } public String getInformationOfTypeB() throws InterruptedException, ExecutionException, TimeoutException { Callable<String> callable = new Callable<String>() { @Override public String call() throws Exception { // Connect to external resource Thread.sleep(1500); return "B"; } }; Future<String> submit = executor.submit(callable); return submit.get(1000, TimeUnit.MILLISECONDS); } } @Test public void testMethodCalls() throws Exception { OnlineResourceAdapter adapter = new OnlineResourceAdapter(); assertNotNull(adapter.getInformationOfTypeA()); assertNotNull(adapter.getInformationOfTypeB()); } } 
-one
source share

All Articles