java跨进程hook_Java进程平滑关闭 Java ShutdownHook机制的应用

package com.gck;

import java.io.*;

import java.util.Date;

import java.util.Random;

import java.util.concurrent.LinkedBlockingQueue;

import java.util.concurrent.TimeUnit;

/**

* Java Shutdown Hook的简单应用(kill -9 不会触发Shutdown hook函数)

* 运行时加载到内存的数据,在系统发生崩溃时,为了防止内存数据丢失,将内存中的数据序列化并保存到本地文件。

* 在下次启动程序时自动加载序列化文件。

*/

public class ShutdownHook {

/**

* 内部类,提供序列化测试

*/

private static class User implements Serializable{

int id; String name;

public User(int id, String name) { this.id = id; this.name = name; }

@Override

public String toString() { return "User{id=" + id + ", name='" + name + "'}"; }

}

// 链式队列

static LinkedBlockingQueue queue = new LinkedBlockingQueue();

// Java进程的shutdown钩子

private static void hook(){

Runtime.getRuntime().addShutdownHook(new Thread(()->{

FileOutputStream fos = null;

ObjectOutputStream oos = null;

try {

System.out.println("开始执行ShutdownHook, 保存队列中的数据");

System.out.println("队列中的数据总数->" + queue.size());

File file = new File("D:/"+ new Date().getTime() +".queue");

fos = new FileOutputStream(file);

oos = new ObjectOutputStream(fos);

User uu = null;

int index = 1;

while((uu = queue.poll()) != null) {

oos.writeObject(uu);

System.out.println("保存第"+(index++)+"个对象.");

}

oos.writeObject(null);//加入null 用来判断是否到末尾,如果不加会报错EOFException

System.out.println("保存队列中的数据完毕【"+file.getAbsolutePath()+"】");

} catch (Exception ex) {

System.out.println(ex.getMessage());

} finally {

try {

fos.close();

oos.close();

} catch (IOException e) {

e.printStackTrace();

}

}

}));

}

public static void main(String[] args) throws InterruptedException, IOException, ClassNotFoundException {

// 初始化shutdown hook

hook();

// 检查序列化文件

File file = new File("D:/1585817262570.queue");

if (file.exists()) {

// 发现序列化文件时,读取该文件并进行解析

FileInputStream fis = new FileInputStream(file);

ObjectInputStream ois = new ObjectInputStream(fis);

User u =null;

while((u=(User)ois.readObject())!=null) {

System.out.println("保存的队列数据->" + u.toString());

queue.offer(u);

}

fis.close();

ois.close();

}

// 数据生产者

new Thread(() -> {

while (true) {

// 随机生成User对象

Random random = new Random();

int r = random.nextInt(200);

User u = new User(r,getRandomChar());

System.out.println("offer->" + u);

// 将User对象存储到队列中

try {

queue.put(u);

// 随机睡眠N秒

TimeUnit.SECONDS.sleep(new Random().nextInt(5));

} catch (InterruptedException e) {

e.printStackTrace();

}

}

}).start();

// 数据消费者

new Thread(() -> {

while (true) {

try {

User u = queue.take();

System.out.println("take->" + u);

// 随机睡眠N秒

TimeUnit.SECONDS.sleep(new Random().nextInt(5));

} catch (InterruptedException e) {

e.printStackTrace();

}

}

}).start();

}

/**

* 随机生成常见汉字

*/

public static String getRandomChar() {

String str = "";

int highCode,lowCode;

Random random = new Random();

highCode = (176 + Math.abs(random.nextInt(39))); //B0 + 0~39(16~55) 一级汉字所占区

lowCode = (161 + Math.abs(random.nextInt(93))); //A1 + 0~93 每区有94个汉字

byte[] b = new byte[2];

b[0] = (Integer.valueOf(highCode)).byteValue();

b[1] = (Integer.valueOf(lowCode)).byteValue();

try {

str = new String(b, "GBK");

} catch (UnsupportedEncodingException e) {

e.printStackTrace();

}

return str;

}

}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值