「Java」タグアーカイブ

【Java】整数を均等にn等分するアルゴリズム

ある整数を可能な限り整数のまま等分したいということがあります。例えば、あるバッチ処理で、処理対象件数が300件だとして、スレッド数が9の場合に各スレッドになるべく均等に処理対象のデータを渡したいとします。

この場合、300を9等分するので、[42, 43, 43, 43, 43, 43, 43] と分割されます。Javaで書くとこんな感じ↓

もちろん、割り切れる場合も同じアルゴリズムです。

amount=300、n=9の値を変更すれば好きな値で動きます。

なぜこれでうまく動くのかというと、簡単に言うと、すべて均等に分けたあとに、余りを1ずつ配っているイメージです。

ここら辺のサイトの説明がわかりやすいです。
https://qiita.com/keisuke-nakata/items/c18cda4ded06d3159109
https://tmtms.hatenablog.com/entry/2016/07/27/ruby-split-array

これを知る前は、なかなかイケてないロジックを書いていたな・・・ (;゚Д゚)y 


Java スレッド処理でsynchronizedを利用する場合の注意(マルチスレッド)

Javaで同期処理を実装する場合、メソッドにsynchronized修飾子をつけて、複数スレッドからの呼び出しを抑止することができます。つまり、2つのスレッドが同時にメソッドを呼び出した場合、先に呼び出したスレッドの処理が優先され、後から呼び出したスレッドは先行するスレッドが終了するまで待たされることになります。

しかし、これには少し注意しなきゃいけないことがあります。それは、「synchronizedメソッドは、そのメソッドが属するインスタンスが複数ある(マルチスレッド)場合は機能しないということです。」

では、マルチスレッドで同期処理を実装するには、どうしたらいいのかというと、下記のようにグローバルに参照可能なロック用オブジェクトを作成して、排他制御をする実装方法があります。

このような実装であれば、Globalクラスのlockというクラス変数のロックがとれない限り、そのスレッドの処理は待たされることになり、複数スレッドによる同期処理を実装することができます。

単に、「なんでもsynchronizedを付ければいいんでしょ?」で実装していた自分が恥ずかしい。。。
(´;д;`) 


【要注意】JavaのFileクラスでrenameToメソッドによるファイル移動

Javaでファイル操作をするときの一番基本的なクラスであるFileクラスには、File操作のためのメソッドが数多く用意されています。
https://docs.oracle.com/javase/jp/8/docs/api/java/io/File.html

その中に、renameToというファイル移動(パスの変更)を行うためのメソッドがあります。

しかし、このrenameToというメソッドを使うには注意が必要です。APIリファレンスはこのように書かれています。

「ファイルシステム間で移動できないことがある」とさらっと書いてありますが、私はこれを見落としており、renameToの戻り値がfalseになってしまいました。Linuxでいうところのパーティションをまたがっていたり、AIXのファイルシステムをまたぐ場合のファイル移動はこのメソッドを使うことはできません。

同じく、APIリファレンスに書いてありますが、Filesクラスにはプラットフォームに依存しないmoveメソッドがあります。が、これはJava 7以降のことなので、Java 6はこんな感じでファイルをコピーして、削除する処理を自作しないといけないです。

今の現場が未だにJava 6を使っており、こんなものまで自分で実装しなくてはならないとは、、、早くバージョンアップしないだろうか。。。