技術メモ

神奈川在住のITエンジニアの備忘録。おもにプログラミングやネットワーク技術について、学んだことを自分の中で整理するためにゆるゆると書いています。ちゃんと検証できていない部分もあるのでご参考程度となりますが、誰かのお役に立てれば幸いです。

Javaのvolatile変数

Javaの「volatile」は、「synchronized の軽量版」という認識しか持っておらず、あまり理解できていない気がしたので、ちょっと調べてみた。

マルチスレッド処理において、フィールド変数に volatile を付けると、各スレッドはその変数を参照する際、スレッド固有の領域ではなく、常に最新の値を見に行く。つまり、各スレッドが古い値を参照してしまうことはなくなる。

synchronized と何が違うのかと言うと、synchronized はロックを取得し、処理中は他のスレッドをブロックするが、volatile はそれはしない。単に、スレッドが対象のフィールド変数を参照する時に、常に最新の値を見れるようになるだけ。これをカッコよく (難しく) 言うと、volatile は「可視性」は持っているが、「アトミック性」は持っていない、ということになるとのこと。
Javaの理論と実践: volatile を扱う

なので、複数スレッドからアクセスされるクラスにおいて、例えば以下のように、あるフィールド変数の値を加算して、加算した結果が特定の数値だったら特別な処理を行いたい場合、synchronized だと実現できるが、volatile では実現できない。

volatile int counter = 0;

void updateCounter {
    counter++;
    if (counter == 100) { // ★
        doSomething();
    }
}

というのは、あるスレッドが counter を加算して counter が 100 になって ★ の箇所に入ろうとしたところに、別スレッドが counter を加算して counter が 101 になってしまう可能性があるからである。そうなると、本来実行したかった doSomething() が実行されない。

こんな感じで volatile は扱うのがちょっと難しいので、基本は synchronized を使い、それだと性能が出ない場合などに volatile を検討するくらいで良いのではないかと考えている。ちなみに、volatile の使いどころについては、以下のページが分かりやすい。
https://relearn-java.com/multithread/#title-how-to-use-volatile
上記によると、volatile の出番はあまりなさそうに思える。

perlで現在時刻を (秒以下の精度で) 取得する。

perl には、現在時刻を取得する関数として localtime 関数がある。ただし、この関数では秒以下の精度で時刻を取得できない。そうしたい場合は、Time::HiRes モジュールの gettimeofday 関数を取得する。gettimeofday関数を使ったサンプルを以下に示す。

use strict;
use warnings;
use Time::HiRes "gettimeofday";

my $currentTimeStr = getCurrentTimeStr();
print $currentTimeStr;

sub getCurrentTimeStr {
    my ($epochSec, $microSec) = gettimeofday();
    my ($sec, $min, $hour, $day, $mon, $year) = localtime($epochSec);
    $year += 1900;
    $mon++;
    return "$year/$mon/$day $hour:$min:$sec.$microSec";
}

上記を実行すると、現在時刻として、例えば、
2018/10/20 23:35:29.844079
が出力される。上記の実行結果の通り、秒以下(マイクロ秒)の精度で現在時刻を取得できる。

SNMP report

SNMP report について、少し調べた時のメモ。

SNMP report は主に SNMPv3 で使用される。SNMPエージェントが、SNMP マネージャからの SNMP リクエストを受け取り、リクエスト処理中に問題が発生した場合などに、SNMP マネージャに SNMP report を返すことがある。SNMP マネージャでは、SNMP report を受け取ったら、その内容を見て SNMP リクエストを修正して再送する等の対応をとれる。

 

参考にしたサイト

https://www.ietf.org/rfc/rfc2572.txt

SNMP Operations (Essential SNMP)

http://net-snmp.sourceforge.net/wiki/index.php/REPORT

 

ライブファイルシステム形式とマスタ形式

WindowsマシンでデータをCDやDVD等のディスクに書き込む場合、その際の形式をライブファイルシステム形式(UDF形式)」「マスタ形式(ISO形式)」から選択する。

ライブファイルシステム形式では、書き込んだデータは後から編集可能である。パソコンからCDやDVDの中身を見た時、ローカルにあるフォルダを見た時と同様に表示される。ただし、WindowsXPより古いマシンでは読み取れない。

一方で、マスタ形式では、Windows以外のパソコンやDVDプレーヤー等の機器でも読み込める。書き込んだデータは個別に編集したり削除したりできない。

 

Windowsマシンを使っている場合の利便性ではライブファイルシステム形式だが、いろんな機器で読み取れる汎用性ではマスタ形式といった感じか。

 

[参考]

https://www.fmworld.net/cs/azbyclub/qanavi/jsp/qacontents.jsp?PID=9710-8358

Windows標準の書込み機能で書き込む(Windows Vista) Q&A情報(文書番号:105384):シャープ

pingで「宛先ホストに到達できません。」が出る場合

存在しない IP アドレスに対して ping コマンドを実行すると、「宛先ホストに到達できません。」と出ることがある。これは、icmp パケットを送信する前段階の arp 要求に対する応答が pingコマンドを実行したマシンまで返ってきていないことを意味している。

 

上記のケースをパケットキャプチャで観察すると、icmp パケットは出ていない。それの前段階の arp 要求が失敗しているので当然ではあるが、上述のことを意識していないと、「あれ?ping コマンドを実行しているのに、icmp パケットがパケットキャプチャに出ない ( ゚д゚)ポカーン」となるので注意。。

bonding インターフェースに対するtcpdump

Linuxには、複数の物理インターフェースを論理的に一つと見なす、bondingという技術がある。

この bonding インターフェースに対して tcpdump コマンドでパケットキャプチャを取得する場合、bonding インターフェースを構成する物理インターフェース(ethX)を tcpdump コマンドの -i オプションで指定すると、パケットの取りこぼしが起き得るらしい。なので、-i オプションには bonding インターフェース(bondX)を指定する。

https://support.hpe.com/hpsc/doc/public/display?docId=emr_na-c03694133

 

当初は、tcpdump を bonding インターフェースに対して実行できるのか、ということを調べていて、上記の記事を見つけた。

Observerパターン

オブジェクト指向デザインパターンの一つである、Observerパターンについて簡単にまとめる。

登場するのはObserver(通知を受ける側)とSubject(通知する側)である。このパターンでは、まずSubjectにObserverを登録する。次に、対象のイベントが発生したら、Subjectが、保持しているObserverのメソッドを呼ぶ(Observerに通知する)。そして、Observerがイベントに対応した処理を実施する、というのがざっくりとした流れである。

オブジェクトを通じて行うコールバックのようなイメージだろうか。