示例
在此示例中,我们要创建一个将生成并输出到控制台的类,该类是在初始化期间作为参数传递的两个整数范围之间的随机数。
public class SimpleRangeRandom implements Runnable {
private int min;
private int max;
private Thread thread;
public SimpleRangeRandom(int min, int max){
this.min= min;
this.max= max;
thread = new Thread(this);
thread.start();
}
@Override
private void WriteObject(ObjectOutputStreamout) throws IO Exception;
private void ReadObject(ObjectInputStream in) throws IOException, ClassNotFoundException;
public void run() {
while(true) {
Random rand = new Random();
System.out.println("Thread: " + thread.getId() + " Random:" + rand.nextInt(max - min));
try {
Thread.sleep(10000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
现在,如果要使此类可序列化,则将存在一些问题。线程是某些不可序列化的系统级类之一。因此,我们需要将线程声明为transient。通过这样做,我们将能够序列化此类的对象,但是仍然会遇到问题。正如您在构造函数中看到的那样,我们设置了随机化器的最小值和最大值,然后启动了负责生成和打印随机值的线程。因此,通过调用readObject()构造函数恢复持久对象时,由于不会创建新对象,因此构造函数将不会再次运行。在这种情况下,我们需要通过在类内部提供两个方法来开发自定义序列化。这些方法是:
private void writeObject(ObjectOutputStream out) throws IOException;
private void readObject(ObjectInputStream in) throws IOException, ClassNotFoundException;
因此,通过在中添加实现,readObject()我们可以启动和启动线程:
class RangeRandom implements Serializable, Runnable {
private int min;
private int max;
private transient Thread thread;
//瞬变应该是无法序列化的任何字段e.gThread或您不想序列化的任何字段
public RangeRandom(int min, int max){
this.min= min;
this.max= max;
thread = new Thread(this);
thread.start();
}
@Override
public void run() {
while(true) {
Random rand = new Random();
System.out.println("Thread: " + thread.getId() + " Random:" + rand.nextInt(max - min));
try {
Thread.sleep(10000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
private void writeObject(ObjectOutputStream oos) throws IOException {
oos.defaultWriteObject();
}
private void readObject(ObjectInputStream in) throws IOException, ClassNotFoundException {
in.defaultReadObject();
thread = new Thread(this);
thread.start();
}
}
这是我们示例的主要内容:
public class Main {
public static void main(String[] args) {
System.out.println("Hello");
RangeRandom rangeRandom = new RangeRandom(1,10);
FileOutputStream fos = null;
ObjectOutputStream out = null;
try
{
fos = new FileOutputStream("test");
out = new ObjectOutputStream(fos);
out.writeObject(rangeRandom);
out.close();
}
catch(IOException ex)
{
ex.printStackTrace();
}
RangeRandom rangeRandom2 = null;
FileInputStream fis = null;
ObjectInputStream in = null;
try
{
fis = new FileInputStream("test");
in = new ObjectInputStream(fis);
rangeRandom2 = (RangeRandom)in.readObject();
in.close();
}
catch(IOException ex)
{
ex.printStackTrace();
}
catch(ClassNotFoundException ex)
{
ex.printStackTrace();
}
}
}
如果运行main,则将为每个RangeRandom实例运行两个线程,这是因为该方法现在同时在构造函数和。Thread.start()readObject()