cuốn sách gpt4 ai đã làm

Java ShutdownHook không thể tham gia luồng chính khi chạy từ JNI

In lại Tác giả: Taklimakan Thời gian cập nhật: 2023-11-01 23:00:54 27 4
mua khóa gpt4 Nike

Tôi có một số mã Java để tạo hook tắt máy để thoát hoàn toàn khi máy khách nhấn ctrl+C:

void tĩnh riêng tư tắt máyHandler (Chủ đề mainThread) {
thử {
mainThread.join(30000);
} bắt (InterruptedException e) {
}
}

public static void main(String[] args) {
Chủ đề cuối cùng mainThread = Thread.currentThread();
Chủ đề tắt máyThread = Chủ đề mới (() -> tắt máyHandler (mainThread));
Runtime.getRuntime().addShutdownHook(shutdownThread);
}

Khi tôi chạy nó từ dòng lệnh, nó hoạt động như mong đợi (luồng chính thoát ra và quay lại dấu nhắc lệnh gần như ngay lập tức). Tuy nhiên, nếu tôi viết một trình bao bọc JNI gọi nó bằng mã C++ sau:

JavaVMInitArgs vm_args;
// Điền vào vm_args

JavaVM *jvm;
JNIEnv *env;
JNI_CreateJavaVM(&jvm, reinterpret_cast(&env), &vm_args);

jclass mainClass = env->FindClass("path/to/my/class");
jmethod mainMethod = env->GetStaticMethodID(mainClass, "main", "([L" STRING_CLASS ";)V");

jclass stringClass = env->FindClass(STRING_CLASS);
jobjectArray mainArgs = env->NewObjectArray(0, stringClass, NULL);

env->CallStaticVoidMethod(mainClass, mainMethod, mainArgs);
jvm->Tiêu diệtJavaVM();

Sau đó tắt máyHandler Phương thức này bị treo cho đến khi hết thời gian chờ 30 giây, sau đó trả lại quyền điều khiển cho mã C++ và cuối cùng thoát ra. Có ai biết cách cho phép khi gọi khởi động từ JNI không tắt máyHandler Có cách nào để tham gia chủ đề chính?

câu trả lời hay nhất

Trong ví dụ đầu tiên của bạn, luồng chính thoát ra, sau đó JVM phát hiện rằng không còn luồng không phải daemon nào và bắt đầu tắt JVM. Tại thời điểm này, không có vấn đề gì khi tham gia luồng chính vì nó kết thúc trước khi nó đóng.

Trong biến thể thứ hai của bạn, luồng chính, tức là thông qua env -> CallStaticVoidMethod(…) thực hiện chủ yếu Luồng của phương thức đang bận thực thi jvm -> hủy JavaVM(). Vì chức năng đó chờ trình xử lý tắt máy hoàn tất và trình xử lý tắt máy của bạn đợi luồng hoàn tất nên bạn gặp bế tắc.

Bạn cũng có thể có được hành vi tương tự bằng cách sử dụng mã Java thuần túy. khi nào bạn sẽ System.exit(0); mặc chủ yếu Khi kết thúc phương thức, hãy để luồng chính bắt đầu tắt máy và đợi nó hoàn tất, bạn sẽ gặp phải tình trạng bế tắc tương tự.

Thông thường bạn không nên thực hiện trong trình xử lý tắt máytham gia vận hành. Những người xử lý này nên dọn dẹp và quay lại càng sớm càng tốt.

hoặc, như the documentation说:

Móc tắt máy chạy vào thời điểm nhạy cảm trong vòng đời của máy ảo và do đó, chúng phải được mã hóa một cách phòng thủ, đặc biệt, chúng phải được viết để đảm bảo an toàn cho luồng và tránh bế tắc trong chừng mực có thể. các dịch vụ có thể đã đăng ký móc tắt máy của riêng chúng và do đó có thể tự tắt trong quá trình tắt. Ví dụ: Các nỗ lực sử dụng các dịch vụ dựa trên luồng khác, chẳng hạn như luồng gửi sự kiện AWT, có thể dẫn đến bế tắc.

Về việc Java ShutdownHook không tham gia được luồng chính khi chạy từ JNI, chúng tôi đã tìm thấy một câu hỏi tương tự trên Stack Overflow: https://stackoverflow.com/questions/52750512/

27 4 0
Chứng chỉ ICP Bắc Kinh số 000000
Hợp tác quảng cáo: 1813099741@qq.com 6ren.com
Xem sitemap của VNExpress