Here is a summary of what to use when performing parallel processing in Java.
There are various types of parallelization, which can be mainly classified according to the type of data to be handled and the number of programs to be run.
The program to write depends on which type of parallelization you want to do.
This is used when you want to execute methods of a certain class at the same time. In the following example, the process written in the call method of TestJob class is executed. At this time, there are two cases, one is to process the method and the other is to get the result.
Write as the following code. I am adding to the job list using an anonymous class. Also, don't forget `` `return null```.
TestParallel.java
public class TestParallel {
static final int threadNum = 4;
public static void main(String[] args) {
//jobs:A class that describes the process you want to execute, threadpool:Thread to execute
Collection<Callable<Void>> jobs = new ArrayList<Callable<Void>>();
ExecutorService threadpool = Executors.newFixedThreadPool(threadNum);
for(int i = 0; i < threadNum; i++){
jobs.add(new Callable<Void>(){
@Override
public Void call() throws Exception {
//This needs to be thread safe
Thread.sleep(100L);
return null;
}
});
}
try {
threadpool.invokeAll(jobs); //Thread execution
threadpool.shutdown();//Do not accept new tasks
if(threadpool.awaitTermination(5L,TimeUnit.MINUTES)){
//Wait 5 minutes
System.out.println("Finish!");
}else{
//Does not end within 5 minutes or ends abnormally
System.out.println("Fail!");
}
} catch (InterruptedException e) {
e.printStackTrace();
threadpool.shutdown();
}
}
}
Write as the following code. This time, I created a class for a job without using an anonymous class. The result is of type `Future <T>`
, which is roughly a type because an instance of type T is returned as a return value. If you call this get () method, it will wait until you get the result.
TestParallel.java
public class TestParallel {
static final int threadNum = 4;
public static void main(String[] args) {
//jobs:A class that describes the process you want to execute, threadpool:Thread to execute
Collection<Callable<String>> jobs = new ArrayList<Callable<String>>();
ExecutorService threadpool = Executors.newFixedThreadPool(threadNum);
List<Future<String>> futures; //Store the result
List<String> result = new ArrayList<String>();
for(int i = 0; i < threadNum;i++){
TestJob t = new TestJob(i);
jobs.add(t);
}
try {
futures = threadpool.invokeAll(jobs); //Thread execution
threadpool.shutdown();//Do not accept new tasks
for(int i = 0; i < threadNum; i++){
//Get results
result.add(futures.get(i).get());
}
for(String s: result){
//View results
System.out.println(s);
}
} catch (InterruptedException | ExecutionException e) {
e.printStackTrace();
threadpool.shutdown();
}
}
}
class TestJob implements Callable<String>{
private int i;
public TestJob(int i){
this.i = i;
}
@Override
public String call() throws Exception {
//This needs to be thread safe
Thread.sleep(100L);
return "thread " + Integer.toString(i);
}
}
In addition to the Executor Service introduced so far, parallel processing using Stream has become possible from Java 8.
TestParallel.java
public class TestParallel {
public static void main(String[] args) {
List<TestJob> jobs = new ArrayList<TestJob>();
for(int i = 0; i < 4; i++){
jobs.add(new TestJob(i));
}
jobs.parallelStream().forEach(x -> {
//This intermediate operation needs to be thread safe
x.doJob();
});
}
}
class TestJob{
private int i;
public TestJob(int i){
this.i = i;
}
public void doJob() {
try {
Thread.sleep(100L);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
If you want to get the result, do you assign it to the list declared in main or something ... However, in that case, the operation at the time of assignment needs to be exclusively controlled, and which thread is the result? I do not know. If you know how to get it like Future, I would appreciate it if you could teach me ...
Let's make a thread obediently. I think MPSD is quite difficult, so here I will write the code using MPMD as an example. It is a process to add "a" to the end for query 1 group and "b" to the end for query 2 group.
TestParallel.java
public class TestParallel {
public static void main(String[] args) {
List<String> query1List = new ArrayList<String>();
List<String> res1 = new ArrayList<String>();
List<String> query2List = new ArrayList<String>();
List<String> res2 = new ArrayList<String>();
for(int i = 0; i < 10; i++){
query1List.add(Integer.toString(i));
query2List.add(Integer.toString(i+10));
}
Thread t1 = new Thread(new Runnable(){
@Override
public void run() {
query1List.stream().forEach(x -> {
res1.add(x + "a");
});
}
});
Thread t2 = new Thread(new Runnable(){
@Override
public void run() {
query2List.stream().forEach(x ->{
res2.add(x + "b");
});
}
});
t1.start();
t2.start();
try {
t1.join();
t2.join();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
If you want to terminate the thread, you can terminate it by raising an exception with `Thread # interrupt ()`
and catching it in the thread. `Thread # stop ()`
is deprecated and should not be used much.
I think that the method of making Thread has been implemented if you have made GUI etc. (Maybe). Furthermore, use `synchronized`
as appropriate for the part that causes conflict, and perform exclusive control.
Until now, I was thinking of parallel processing with multiple threads, but you can also create an external process and run it in parallel. The code below unpacks hoge.tar.gz. Here, the waitiFor method waits for the end, but it is also possible to proceed as it is without waiting.
TestParallel.java
public class TestParallel {
ProcessBuilder pb = new ProcessBuilder(new String[] {"tar", "zxvf", "hoge.tar.gz"});
try {
Process p = pb.start();
p.waitFor();
} catch (IOException | InterruptedException e) {
e.printStackTrace();
}
}
Personally, I liked Java 8 notation very concisely. Basically, parallelization is easier if you parallelize data in parallel where there is no conflict (naturally). Also, I would appreciate it if you could tell me if there are other methods like this.
Recommended Posts