I would like to use 2 methods in the same class concurrently using the same object in Java. For example:
public class aThread extends Thread {
int countA = 0;
int countB = 0;
int countA(){
for (int i = 0; i < 1000; i++) {
countA++;
}
return countA;
}
int countB(){
for (int i = 0; i < 1000; i++) {
countB++;
}
return countB;
}
@Override
public void run() {
super.run();
//should there be something here?
}
}
And using this methods in another method:
public class MainClass {
public static void main(String[] args) {
aThread myThread = new aThread();
myThread.countA(); //I want these 2 methods to run concurrently.
myThread.countB();
//how do I use myThread.start() here?
}
}
note: They don’t have to be synchronized.
Advertisement
Answer
There are several ways to achieve your task. You have quiet easy situation when threads should not be synchronized.
You can use ExecutorService from Java Concurrency:
public class ConcurrentCode {
private int countA = 0;
private int countB = 0;
int countA(){
for (int i = 0; i < 1000; i++) {
countA++;
}
System.out.println(countA);
return countA;
}
int countB(){
for (int i = 0; i < 1000; i++) {
countB++;
}
System.out.println(countB);
return countB;
}
public void execute(){
ExecutorService executorService = Executors.newFixedThreadPool(2);
// method reference introduced in Java 8
executorService.submit(this::countA);
executorService.submit(this::countB);
// close executorService
executorService.shutdown();
}
public static void main(String[] args){
new ConcurrentCode().execute();
}
}
Remember to shutdown ExecutorService otherwise your application won’t stop because it will have alive threads.
Or you can have the simplest approach using vanilla Java threads:
public void executeInNativeThreads(){
// starts new thread and executes countA in it
new Thread(this::countA).start();
// starts new thread and executes countB in it
new Thread(this::countB).start();
}
To get computation results you can get the Future<Integer> from executorService and then you have a choice:
- poll
Futureif it is done - wait until the
Futurewill be completed. - wait explicitly for a certain timeout
Here is an example:
public void execute() throws Exception {
ExecutorService executorService = Executors.newFixedThreadPool(2);
Future<Integer> future1 = executorService.submit(this::countA);
Future<Integer> future2 = executorService.submit(this::countB);
// wait until result will be ready
Integer result1 = future1.get();
// wait only certain timeout otherwise throw an exception
Integer result2 = future2.get(1, TimeUnit.SECONDS);
System.out.println("result1 = " + result1);
System.out.println("result2 = " + result2);
executorService.shutdown();
}
Note, while we are explicitly waiting for result of future1, future2 is still being executed in another thread. It means that there won’t be big delay in computation of future2 in particularly this example.
Also, take a look at CompletionStage which is used in asynchronous computations.