2012-03-21 6 views
1

後のロックの状態は、次のコードは何である:考えるとデシリアライズ

import java.io.Serializable; 
import java.util.concurrent.locks.ReentrantLock; 

class Data 
{ 
    private int value; 

    Data (int value) 
    { 
     this.value = value; 
    } 
} 

public class InfoCollection implements Serializable 
{ 
    private Data[] data; 
    private static final long serialVersionUID = 1L; 
    private transient ReentrantLock _lock = new ReentrantLock(); 

    public InfoCollection (int datasize) 
    { 
     this.data = new Data[datasize]; 
    } 

    public setData (Data newdata, int index) 
    { 
     _lock.lock(); 

     try 
     { 
      this.data[index] = newdata; 
     } 
     finally 
     { 
      _lock.unlock(); 
     } 
    } 
} 

はのは、私はタイプInfoCollectionのオブジェクトを作成すると、それをシリアル化してみましょう。しばらくすると、私はそれを逆シリアル化して使いたいと思っています。デシリアライズ後、_lockフィールドはどのような状態になりますか?ロックまたはアンロック? nullまたはnullではない?どうして ?

これは実際にそれを実行してロックの状態を確認することで簡単に見つけることができますが、私はそれを論理的に把握したいと思います。

デシリアライズ後に、コンストラクタが任意のメソッド/コンストラクタの外で呼び出されるため、クラス/オブジェクトのロードによってコンストラクタの呼び出しが発生することが考えられます(コンストラクタはロックされていないオブジェクトを提供します)結果として。私は正しいですか? 1.5ステート明示的にJDKでReentrantLockため

答えて

1

はnullになります。

_lock - 一時的に - 格納されていないため、復元されません。コンストラクタは呼び出されません

private transient ReentrantLock _lock = new ReentrantLock();

(データは直列化可能ではありません NOTE

、あなたはメソッドが実装されていない:

private void writeObject(java.io.ObjectOutputStream out) 
    throws IOException 
private void readObject(java.io.ObjectInputStream in) 
    throws IOException, ClassNotFoundException; 

+0

はい、私は 'Data'が直列化させるのを忘れていました。私の悪い。シリアライズ可能とマークされていると仮定しましょう。デシリアライズ後に '_lock'を外部にアクセスせずに' _lock'をnullにしない方法はありますか?私は 'transient'キーワードを削除することができます。しかし、実際にはLockをシリアル化するのは理にかなっていますか? –

2

のJavadoc:あなたの例のロックで

* 
* <p>Serialization of this class behaves in the same way as built-in 
* locks: a deserialized lock is in the unlocked state, regardless of 
* its state when serialized.