Android Summarized

【Java】スレッドについてまとめてみました

投稿日:2019年11月25日 更新日:

はじめに

こんにちは、matsunariです。今回はJavaのスレッドについてまとめてみます。なんとなく理解はしていましたが、きちんと整理できていなかったので今回まとめてみようと思いました。スレッドをきちんと理解することでバグのないアプリ製作に役立てられればいいなと思っています。

スレッドの基本について

プログラムを実行する処理の最小単位を”スレッド”といいます。通常アプリはメインスレッドと呼ばれる一本のスレッド(シングルスレッド)の上で動きます。しかし、ネットワーク通信などのように処理に時間がかかる動作を行う場合、シングルスレッドでは通信が終わってからようやく次の処理に移ります。これでは、ユーザーは処理が終わるまで長時間待たなければなりません。Javaの世界ではメインスレッドだけではなく、複数のスレッドを並行して実行することができます。これをマルチスレッドと呼びます。マルチスレッドを利用することで、アプリが裏で通信を行なっている間でも、同時並行的に他の動作を行うことができます。

スレッドの利用

スレッドを利用するにはThreadクラスを継承することで実現できます。
主に以下のような2種類の方法を使います。
・Threadクラスを継承する
・Runnnableクラスを実装する

Threadクラス

まずはThreadクラスを使ってスレッドを作ってみましょう。

これでThreadクラスを継承したThreadBasicクラスができました。Threadクラスを使用するときは、必ずrun()メソッドをオーバーライドする必要があります。
このrun()メソッドはJavaでいうところmainメソッドのようなもので、スレッド開始時に呼び出されるエントリーポイントです。
ここにThreadで行いたい処理を書きましょう。
今回は0-50の間でカウントアップを行う処理行なっています。

それでは実際にスレッドを使って処理を行うとどのようになるのかみてみましょう。
MainActivityではThreadクラスをインスタンス化し、3つのスレッドを作りました。それぞれ、start()メソッドを実行して並行して実行します。


順番が交互になって処理結果が表示されています。
これで各スレッドで処理が並列的に実行されたことを確認できましたね。

Runnableインターフェース

同様にRunnableインタフェースを実装した場合はこのようになります。

生成&実行処理はこちらです。

Threadクラスとの違いはほとんどありません。

同期処理

別々の処理を並行的に実施できるとはいえ、同一のメモリ上で処理されるので、共有のデータに対して同時に処理を行った場合、不整合が発生するケースがあります。

これは50万個のスレッドを並行してカウントアップするプログラムです。
このプログラムを実行すると正しく動作しない可能性があります。
理由としては以下のようなケースが起こり得るからです。

BadCountクラスのcountUp()メソッドの処理で「変数の現在地を取得→値を加算→演算結果の再代入」という手順を行なっています。
処理の途中で他のスレッドの割り込みが入ると結果が正しく反映されない可能性があります。

synchronized修飾子

上述した不整合を防ぐために、synchronized修飾子を利用します。

synchronized修飾子が指定されると、そのメソッドが複数のスレッドから同時に呼び出されることがなくなります。ほぼ同時に呼び出されたとしても、先に呼び出した方の処理が優先され、先に呼び出された方で処理が完了するまで、次のスレッドで呼び出されず待ちの状態となります。このように特定の処理を占有することロックを獲得すると呼んだりもします。ロックを獲得して処理を行うことを同期処理と呼びます。

おわりに

今回はJavaのスレッド処理に関してまとめてみました。スレッドはまだ奥が深そうな分野なので、引き続き学習してブログでも発信していきたいと思っています。

おすすめ書籍

AndroidエンジニアのためのモダンJava [改訂新版]Android SDK ポケットリファレンス スッキリわかるJava入門 第3版 (スッキリシリーズ)

blog-page_footer_336




blog-page_footer_336




-Android, Summarized
-,

執筆者:

免責事項

このブログは、記事上部に記載のある投稿日時点の一般的な情報を提供するものであり、投資等の勧誘・法的・税務上の助言を提供するものではありません。仮想通貨の投資・損益計算は複雑であり、個々の取引状況や法律の変更によって異なる可能性があります。ブログに記載された情報は参考程度のものであり、特定の状況に基づいた行動の決定には専門家の助言を求めることをお勧めします。当ブログの情報に基づいた行動に関連して生じた損失やリスクについて、筆者は責任を負いかねます。最新の法律や税務情報を確認し、必要に応じて専門家に相談することをお勧めします。


comment

メールアドレスが公開されることはありません。 が付いている欄は必須項目です

CAPTCHA


関連記事

【Java】ストリームについてまとめてみました

1 はじめに2 Streamの分類3 テキストファイルの読み書き4 バイナリファイルの読み書き5 読み書きのバッファリング処理6 さいごに7 おすすめ書籍 はじめに Javaではすべての入出力をストリ ...

GCM 2.0からFCMに移行する(AWS SNS対応版)

1 はじめに2 FCM移行で大事なポイント3 Firebaseプロジェクトへの引き継ぎ3.1 Firebaseの初期設定4 依存ライブラリの変更4.1 “com.google.androi ...

【Kotlin】Glideで角丸の画像を作成する

1 はじめに2 使用するライブラリのインポート3 Glideで画像を読み込む4 オプションまとめ5 さいごに6 おすすめ書籍 はじめに こんにちは。miyagawaです。 今回はGlideを使って角丸 ...

Pushwoosh UnityでのFCM移行

1 はじめに2 Firebaseプロジェクトの引き継ぎ3 PushwooshのAPIキーの差し替え3.1 FCMサーバーキーの取得3.2 google-services.jsonのダウンロード3.3 ...

Kotlin OkHttp3で通信を行なった際の備忘

1 はじめに2 ライブラリの導入方法3 Build時にエラーが発生する4 パーミッションの追加5 main関数で同期処理の通信6 onFailureでUnable to resolve host &# ...

フォロー

blog-page_side_responsive

2019年11月
 12
3456789
10111213141516
17181920212223
24252627282930

アプリ情報

私たちは無料アプリもリリースしています、ぜひご覧ください。 下記のアイコンから無料でダウンロードできます。