LoginSignup
6
4

More than 5 years have passed since last update.

様々な言語における並行、並列処理(Java編)

Last updated at Posted at 2017-02-21

前回と同じことをJavaでしてみよう。

long.java

public class Main {

    private static final int REPEAT = 500000000;

    private static long a = 0;

    public static void main(String[] args) throws InterruptedException{

        Thread th1 = new Thread(new Runnable() {
            @Override
            public void run() {
                for(int i = 0;i <REPEAT; i++){
                    a = 1;
                    check();
                }
            }
        });

        Thread th2 = new Thread(new Runnable() {
            @Override
            public void run() {
                for(int i = 0;i <REPEAT; i++){
                    a = -1;
                    check();
                }
            }
        });

        th1.start();
        th2.start();

        th1.join();
        th2.join();

        System.out.println("FINISHED!");
    }

    private static void check(){
        if(a != 1 && a != -1){
            System.out.println("LONG VALUE HAS BROKEN!");
        }
    }
}

排他制御ではないが、Javaで同様の問題を解決するにはvolatile修飾子がある
private volatile static long a = 0;
とすれば問題がなくなる。

volatileには「値の参照の際に、常に最新の値を見に行く」という性質があり、
ざっくり言えば、volatileの代入や参照はロックされているような振る舞いをする。

でもこれでは安全と言えないので、AtomicLongを使う。
アトミック: 不可分操作。ある操作を行なうときに他者がその操作に割り込めないことを指す。
private static AtomicLong a = new AtomicLong(0)

引用: http://d.hatena.ne.jp/cero-t/20120830/1346267076

Javaでの排他制御には、synchronizedブロックが使える。

synchronized
public class Main {

    private static final int REPEAT = 500000000;

    private static Long a = new Long(0);

    public static void main(String[] args) throws InterruptedException{

        Thread th1 = new Thread(new Runnable() {
            @Override
            public void run() {
                for(int i = 0;i <REPEAT; i++){
                    synchronized (a){
                        a = new Long(1);
                        check();
                    }
                }
            }
        });

        Thread th2 = new Thread(new Runnable() {
            @Override
            public void run() {
                for(int i = 0;i <REPEAT; i++){
                    synchronized (a) {
                        a = new Long(-1);
                        check();
                    }
                }
            }
        });

        th1.start();
        th2.start();

        th1.join();
        th2.join();

        System.out.println("FINISHED!");
    }

    private static void check(){
        if(a != 1 && a != -1){
            System.out.println("LONG VALUE HAS BROKEN!");
        }
    }
}

Javaで並列処理を行うには、Stream#parallelが使える。

parallel
public class Main {

    public static void main(String[] args) {
    // write your code here
        IntStream.range(1,10).parallel().forEach(System.out::println);
    }
}
6
4
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
6
4