質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.50%
Java

Javaは、1995年にサン・マイクロシステムズが開発したプログラミング言語です。表記法はC言語に似ていますが、既存のプログラミング言語の短所を踏まえていちから設計されており、最初からオブジェクト指向性を備えてデザインされています。セキュリティ面が強力であることや、ネットワーク環境での利用に向いていることが特徴です。Javaで作られたソフトウェアは基本的にいかなるプラットフォームでも作動します。

同期

複数のディレクトリに存在するファイルを更新した場合に、すべてのファイルにも更新が行われる事、又は、同じ記憶領域に同時にアクセスして内容の整合性が失われてしまう事をを防ぐ制御などを同期と呼びます。

Q&A

解決済

2回答

3535閲覧

[Java]synchronizedブロックの使用箇所

shiita

総合スコア16

Java

Javaは、1995年にサン・マイクロシステムズが開発したプログラミング言語です。表記法はC言語に似ていますが、既存のプログラミング言語の短所を踏まえていちから設計されており、最初からオブジェクト指向性を備えてデザインされています。セキュリティ面が強力であることや、ネットワーク環境での利用に向いていることが特徴です。Javaで作られたソフトウェアは基本的にいかなるプラットフォームでも作動します。

同期

複数のディレクトリに存在するファイルを更新した場合に、すべてのファイルにも更新が行われる事、又は、同じ記憶領域に同時にアクセスして内容の整合性が失われてしまう事をを防ぐ制御などを同期と呼びます。

0グッド

0クリップ

投稿2016/11/23 05:12

###前提・実現したいこと
synchronizedブロックを使用する箇所が、一般的な書き方ではどこになるのかが気になりました。

###該当のソースコード

Java

1public class Test { 2 public static void main(String[] args) { 3 Count count = new Count(); 4 ThreadC[] threadC = new ThreadC[10]; 5 for (int i = 0; i < 10; i++) { 6 threadC[i] = new ThreadC(count); 7 threadC[i].start(); 8 } 9 10 for (int i = 0; i < 10; i++) { 11 try { 12 threadC[i].join(); 13 } 14 catch (InterruptedException e) { 15 e.printStackTrace(); 16 } 17 } 18 19 System.out.println(count.getCount()); 20 } 21} 22 23public class Count { 24 private int count = 0; 25 26 public void add() { 27 synchronized (this) { 28 count += 10; 29 } 30 } 31 32 public int getCount() { 33 return count; 34 } 35} 36 37public class ThreadC extends Thread { 38 Count count; 39 40 public ThreadC(Count count) { 41 this.count = count; 42 } 43 44 public void run() { 45 for (int i = 0; i < 10000; i++) { 46 count.add(); 47 } 48 } 49}

Countクラスのインスタンスを渡した10個のスレッドを同期させて、全てのスレッドが終了してから結果を表示するプログラムです。
###別の書き方
ここで次のようにsynchronizedブロックを利用しても、うまく同期処理ができると思うのですが、どちらの書き方が一般的に使われているのでしょうか?使い分けなどがありましたら、そのことについても教えていただきたいです。

Java

1// synchronizedブロックを消した 2public class Count { 3 private int count = 0; 4 5 public void add() { 6 count += 10; 7 } 8 9 public int getCount() { 10 return count; 11 } 12} 13 14// synchronizedブロックを追加した 15public class ThreadC extends Thread { 16 Count count; 17 18 public ThreadC(Count count) { 19 this.count = count; 20 } 21 22 public void run() { 23 for (int i = 0; i < 10000; i++) { 24 synchronized (count) { 25 count.add(); 26 } 27 } 28 } 29}

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答2

0

ベストアンサー

synchronizedブロックを使用する箇所が、一般的な書き方ではどこになるのかが気になりました。

対象とするクラスの設計、特に スレッド・セーフに関する設計 によって適切な箇所は異ります。

  • Countクラス自身を「スレッド・セーフなカウンタ」とする設計では、同クラスを利用するマルチスレッド処理コードでは同期制御を意識しません。この場合、Countクラス内部実装にてsynchronizedによる同期制御を行う必要があります。マルチスレッド処理からは安全にCountクラスを利用できる点がメリットですが、一般にスレッドセーフ実装では実行時コスト増加(≒処理が遅くなる)を避けられません。

  • Countクラスを「マルチスレッドを特に考慮しないカウンタ」とする設計では、同クラスをマルチスレッド処理コードから利用する場合、Countクラスを利用する側のコードでsynchronizedによる同期制御を行う必要があります。マルチスレッド処理の必要がないときに無駄な実行コスト増はありませんが、マルチスレッド処理が必要な時には利用者側に同期制御の責任を押し付けることになります(≒使う側が間違うとアウト)。

Countクラス設計においてどちらを選択するかはクラス提供者の判断であり、synchronizedはその設計に合わせて適切に利用する必要があります。

投稿2016/11/23 08:28

編集2016/11/23 08:30
yohhoy

総合スコア6189

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

shiita

2016/11/23 09:45

回答ありがとうございます。このプログラムでは、Countクラスは必ずマルチスレッド処理を行うものだったので、Countクラス内部でsynchronizedを使おうと思います。 違いがよくわかりました。
guest

0

最も簡単な使い分け

java

1//Countを使うスレッドが複数ある場合 2 3public class Te2 { 4 public static void main(String[] args) { 5 Count count = new Count(); 6 ThreadC[] threadC = new ThreadC[10]; 7 for (int i = 0; i < 10; i++) { 8 threadC[i] = new ThreadC(count); 9 threadC[i].start(); 10 } 11 ThreadD[] threadD = new ThreadD[10]; 12 for (int i = 0; i < 10; i++) { 13 threadD[i] = new ThreadD(count); 14 threadD[i].start(); 15 } 16 17 18 for (int i = 0; i < 10; i++) { 19 try { 20 threadC[i].join(); 21 22 } 23 catch (InterruptedException e) { 24 e.printStackTrace(); 25 } 26 } 27 for (int i = 0; i < 10; i++) { 28 try { 29 threadD[i].join(); 30 31 } 32 catch (InterruptedException e) { 33 e.printStackTrace(); 34 } 35 } 36 37 System.out.println(count.getCount()); 38 } 39} 40 41 class Count { 42 private int count = 0; 43 44 public void add() { 45 synchronized (this) {//synchronizedはCount内に配置すると一回書くだけで済む 46 count += 10; 47 } 48 } 49 50 public int getCount() { 51 return count; 52 } 53} 54 55 class ThreadC extends Thread {//スレッド1 56 Count count; 57 58 public ThreadC(Count count) { 59 this.count = count; 60 } 61 62 public void run() { 63 for (int i = 0; i < 10000; i++) { 64 count.add(); 65 } 66 } 67} 68 69 class ThreadD extends Thread {//スレッド2 70 Count count; 71 72 public ThreadD(Count count) { 73 this.count = count; 74 } 75 76 public void run() { 77 for (int i = 0; i < 10000; i++) { 78 count.add(); 79 } 80 } 81}

java

1//Count内使用メソッドが複数ある場合 2 3public class Te4 { 4 public static void main(String[] args) { 5 Count count = new Count(); 6 ThreadC[] threadC = new ThreadC[10]; 7 for (int i = 0; i < 10; i++) { 8 threadC[i] = new ThreadC(count); 9 threadC[i].start(); 10 } 11 12 for (int i = 0; i < 10; i++) { 13 try { 14 threadC[i].join(); 15 } 16 catch (InterruptedException e) { 17 e.printStackTrace(); 18 } 19 } 20 21 System.out.println(count.getCount()+" "+count.getCount2()); 22 } 23} 24 25class Count { 26 private int count = 0; 27 private int count2 = 0; 28 29 public void add() {//Count内使用メソッド1 30 count += 10; 31 } 32 33 public int getCount() { 34 return count; 35 } 36 37 public void add2() {//Count内使用メソッド2 38 count2 += 10; 39 40 } 41 42 public int getCount2() { 43 return count2; 44 } 45 46 47} 48class ThreadC extends Thread { 49 Count count; 50 51 public ThreadC(Count count) { 52 this.count = count; 53 } 54 55 public void run() { 56 for (int i = 0; i < 10000; i++) { 57 synchronized (count) {//synchronizedはrun内に配置すると一回書くだけで済む 58 count.add(); 59 count.add2(); 60 } 61 } 62 } 63}

投稿2016/11/23 06:05

退会済みユーザー

退会済みユーザー

総合スコア0

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

shiita

2016/11/23 09:34

回答ありがとうございます。わかりやすい具体例参考になりました。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.50%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問