Abh*_*ary 7 java serialization
java中的一个线程无法在Java中重启,所以我实现了一个java Thread,然后在获取Thread的序列化对象后尝试重启该线程.
import java.io.Serializable;
public class ThreadSerialization extends Thread implements Serializable {
int iCheck = 10;
@Override
public void run() {
System.out.println("STARTING");
for(int i=0;i<10;i++){
iCheck+=i;
}
}
}
Run Code Online (Sandbox Code Playgroud)
和序列化算法 -
public class CallingThreadSerializable {
public static void main(String[] args) {
ThreadSerialization ser = new ThreadSerialization();
ser.start();
FileOutputStream fos = null;
ObjectOutputStream out = null;
FileInputStream fis = null;
ObjectInputStream ois = null;
try {
fos = new FileOutputStream("thread.ser");
out = new ObjectOutputStream(fos);
out.writeObject(ser);
} catch (FileNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} finally {
try {
out.close();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
try {
fis = new FileInputStream("thread.ser");
ois = new ObjectInputStream(fis);
ThreadSerialization ser1 = (ThreadSerialization) ois.readObject();
System.out.println("---> " + ser1.iCheck);
ser1.start();
System.out.println("---> " + ser1.iCheck);
ois.close();
} catch (FileNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (ClassNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
Run Code Online (Sandbox Code Playgroud)
输出 -
STARTING
---> 55
---> 55
STARTING
Run Code Online (Sandbox Code Playgroud)
为什么ser1对象再次启动?
A.H*_*.H. 16
有两点:
第一:Thread不是Serializable,因此serializableJavaDoc 的以下摘录适用:
为了允许序列化非可序列化类的子类型,子类型可以承担保存和恢复超类型的公共,受保护和(如果可访问)包字段的状态的责任.
这意味着,您的班级ThreadSerialization将有责任存储和恢复状态Thread.但由于很多private领域,你不能这样做Thread.因此,所有私有字段Thread都默认初始化.现在看看实施Thread.start():
//...
if (threadStatus != 0)
throw new IllegalThreadStateException();
// ...
start0();
//...
Run Code Online (Sandbox Code Playgroud)
由于threadStatus尚未正确存储/恢复,您可以再次启动.
第二:不要混淆实际的操作系统线程和"管理器"对象java.lang.Thread- 它们只是松散耦合.在您的示例中,您只序列化管理器,但不序列化在Java中没有表示的OS线程.反序列化后,您有第二个管理器实例,没有附加OS线程.所以告诉经理开始会成功.
如果你反序列化(?)一个Object,那么你实际上是在创建一个具有与原始Object相同属性的新类实例.
它不是同一个对象.
同样,由于Thread本身不实现Serializable,因此启动性实际上是任何Serializable子类中的瞬态状态的一部分(因为中断),因为序列化不会恢复从非Serializable超类继承的字段.任何类extends Thread implements Serializable,假设有一个很好的理由这样做的所有,也许应该有自己的领域来跟踪startedness和interruptedness,并调用Thread.start()和Thread.interrupt()在readObject()或readResolve()恢复其状态的那些元素.