見出し画像

応用情報に駆け込んで ネイティブアプリケーション編


はじめに

応用情報本番まであと3日。
午後の部は情報システム開発にしようと思ったら、過去にアプリの処理が出題されてた。
スマホの「ネイティブアプリケーション」だ。設問中の開発者さんが「Webアプリケーション」とどっちにしよっかなって考えていわゆるアプリを選んだらしい。開発はJAVAだそうだ。
少しかじった程度だ。たぶんLollipopかMarshmallow時代だと思う。本を見まねにTwitterのクライアンを作って非同期でくじけてやめた。

  • Android: Java or Kotlin

  • iOS: Objective-C or Swift

なんで本日も即席のガイドブックを生成AIたちに作ってもらったよ。


応用情報技術者のためのモバイル並行処理入門

DALL·EはAndroid派かもしれない

1. 高度な概念と実装

  1. 非同期処理 (Asynchronous Processing):

    • 処理の完了を待たずに次の処理を開始する手法

    • Android: AsyncTask(非推奨), Coroutines, CompletableFuture

    • iOS: DispatchQueue.async, Combine, async/await (iOS 13+)

  2. バックグラウンド処理 (Background Processing):

    • UIをブロックせずに実行される処理

    • Android: WorkManager, IntentService, JobScheduler

    • iOS: BackgroundTasks framework, URLSession background tasks

  3. 並行処理 (Concurrent Processing):

    • 複数のタスクを見かけ上同時に実行する手法

    • Android: ExecutorService, Coroutines

    • iOS: DispatchQueue.concurrent, OperationQueue

  4. 並列処理 (Parallel Processing):

    • 複数のタスクを実際に同時に実行する手法(マルチコア利用)

    • Android: ForkJoinPool, Parallel Streams

    • iOS: DispatchQueue.concurrentPerform, Grand Central Dispatch

  5. スレッドプール (Thread Pool):

    • 再利用可能なスレッドの集合

    • Android: ExecutorService.newFixedThreadPool()

    • iOS: NSOperationQueue(内部的にスレッドプールを使用)

  6. コルーチン (Coroutine):

    • 協調的にマルチタスクを実現する軽量スレッド

    • Android: Kotlin Coroutines

    • iOS: Swift Concurrency (async/await, iOS 13+)

  7. タスクキュー (Task Queue):

    • 実行待ちのタスクを管理するデータ構造

    • Android: HandlerThread, WorkManager

    • iOS: DispatchQueue, OperationQueue

  8. ワーカースレッド (Worker Thread):

    • バックグラウンドでタスクを処理するスレッド

    • Android: HandlerThread, WorkManager Worker

    • iOS: DispatchQueue.global().async { }

  9. メインスレッド (Main Thread) / UIスレッド (UI Thread):

    • UIの更新や描画を行う主要なスレッド

    • Android: runOnUiThread { }, Handler(Looper.getMainLooper())

    • iOS: DispatchQueue.main.async { }

  10. ハンドラー (Handler):

    • スレッド間通信とメッセージングを管理

    • Android: Handler, Looper

    • iOS: 直接的な等価物はないが、DispatchQueue等で類似機能を実現

2. スレッド制御の基本

  1. スレッド作成:

    • Android: new Thread(() -> { }).start()

    • iOS: DispatchQueue.global().async { }

  2. スレッド終了:

    • Android: thread.interrupt()

    • iOS: (GCDでは明示的な終了は不要)

  3. 同期メカニズム:

    • a) ミューテックス (相互排他):

      • 1つのスレッドのみがリソースにアクセス可能

      • Android: synchronized(object) { } または ReentrantLock

      • iOS: NSLock または DispatchQueue(label: "com.example").sync { }

    • b) セマフォ:

      • 複数のスレッドが同時にリソースにアクセス可能(上限あり)

      • Android: Semaphore semaphore = new Semaphore(permits)

      • iOS: DispatchSemaphore(value: permits)

  4. 条件変数:

    • Android: object.wait(); object.notify(); object.notifyAll()

    • iOS: NSCondition

  5. スレッド間通信:

    • Android: Handler, LiveData, または EventBus

    • iOS: NotificationCenter または Combine

  6. デッドロック回避 (タスクチェック):

    • リソースの獲得順序を一貫させる

    • タイムアウトの使用: obj.wait(timeout), lock.tryLock(time, unit)

    • 循環依存を検出するツールの使用 (Thread Dump解析)

  7. スレッドスケジューリングと優先度:

    • Android: thread.setPriority(Thread.MAX_PRIORITY)

    • iOS: DispatchQueue.global(qos: .userInitiated).async { }

  8. スレッド一時停止:

    • Android: object.wait() または LockSupport.park()

    • iOS: condition.wait() または semaphore.wait()

  9. スレッド再開:

    • Android: object.notify() または LockSupport.unpark(thread)

    • iOS: condition.signal() または semaphore.signal()

  10. スレッド結合:

    • Android: thread.join()

    • iOS: DispatchGroup

  11. アトミック操作:

    • Android: AtomicInteger, AtomicReference

    • iOS: OSAtomicIncrement32, OSAtomicDecrement32

  12. ロック/アンロック:

    • Android: ReentrantLock lock = new ReentrantLock(); lock.lock(); lock.unlock()

    • iOS: NSLock lock = NSLock(); lock.lock(); lock.unlock()

  13. Wait と Notify の関係:

    • Wait: スレッドを一時停止し、条件を待つ

    • Notify: 待機中のスレッドに条件成立を通知

    • 使用例:

      • synchronized(obj) { while(!condition) { obj.wait(); } }

      • 別スレッドで:

        • synchronized(obj) { condition = true; obj.notify(); }

3. ベストプラクティスと注意点

  1. UIの更新は必ずメインスレッドで行う

  2. 長時間実行される処理はバックグラウンドで実行

  3. スレッドの直接管理よりも、高レベルの抽象化(ExecutorService, GCD等)を使用

  4. デッドロック回避のため、複数のロックの獲得は常に同じ順序で行う

  5. リソースの過剰な占有を避けるため、ロックの保持時間は最小限に

  6. 可能な限り、スレッドセーフなデータ構造やイミュータブルオブジェクトを使用

  7. 適切なエラーハンドリングと例外処理を実装

  8. パフォーマンスとレスポンシビリティのバランスを考慮

4. プラットフォーム推奨の高レベルAPI

  • Android:

    • Kotlin Coroutines: 構造化された非同期プログラミング

    • RxJava: リアクティブプログラミング

    • LiveData: ライフサイクル認識型データホルダー

    • ViewModel: UI関連データの保持と管理

    • WorkManager: 制約付きバックグラウンドジョブの管理

  • iOS:

    • Grand Central Dispatch (GCD): 低レベルの並行処理API

    • Operation and OperationQueue: 高レベルの並行処理抽象化

    • Combine: 宣言的な非同期プログラミングフレームワーク

    • Swift Concurrency: async/await, Actor model (iOS 13+)

注意:
このガイドは基本的な概念と実装方法を示していますが、実際の開発では各プラットフォームの最新のベストプラクティスとAPIを使用することが推奨されます。例えば、長時間実行されるバックグラウンドタスクには、AndroidではWorkManageriOSではBackgroundTasks frameworkを活用するのが最適です。また、低レベルのスレッド操作よりも、AndroidではCoroutinesiOSではasync/awaitCombineなどの高レベルな抽象化を使用することが一般的です。これにより、コードの保守性や可読性が大幅に向上します。

いいなと思ったら応援しよう!

この記事が参加している募集