2009-07-15 28 views
13

Tôi có một số lớp sử dụng cùng thư viện JNI, được gọi là "jni". Trong mỗi trong những lớp học, tôi có một cuộc gọi System.loadLibrary() trong initializer tĩnh của lớp:Ngăn không cho Java tải thư viện nhiều hơn một lần

Class class1 { 
    static{ 
     System.loadLibrary("jni"); 
    } 
    ... 
} 

Class class2 { 
    static{ 
     System.loadLibrary("jni"); 
    } 
    ... 
} 

Vấn đề duy nhất là, tôi chỉ muốn System.loadLibrary() được gọi là một lần, vì nó có thể mất một lúc. Có một cách dễ dàng và sạch sẽ để ngăn chặn nhiều tải của cùng một thư viện?

Trả lời

30

Nếu thư viện đã được tải bất kỳ lệnh gọi tiếp theo nào để tải cùng một thư viện sẽ bị bỏ qua.

System.loadLibrary:

Nạp thư viện hệ thống theo quy định của lập luận libname. Cách thức trong tên thư viện được ánh xạ tới thư viện hệ thống thực tế là hệ thống phụ thuộc.

Cuộc gọi System.loadLibrary (tên) là có hiệu quả tương đương với các cuộc gọi

Runtime.getRuntime().loadLibrary(name) 

Runtime.loadLibrary:

tải thư viện năng động với tên thư viện quy định. Một tệp chứa mã gốc được tải từ hệ thống tệp cục bộ từ một địa điểm nơi các tệp thư viện được thông thường là thu được. Chi tiết của quá trình này phụ thuộc vào việc triển khai thực hiện. Việc ánh xạ từ tên thư viện đến tên tệp cụ thể được thực hiện theo cách thức cụ thể theo hệ thống .

Đầu tiên, nếu có người quản lý bảo mật, phương thức kiểm tra liên kết của nó được gọi là tên libname làm đối số của nó. Điều này có thể dẫn đến ngoại lệ bảo mật.

Phương thức System.loadLibrary (String) là phương tiện thông thường và thuận tiện có nghĩa là gọi phương thức này. Nếu phương pháp tự nhiên sẽ được sử dụng trong việc thực hiện của một lớp, một chiến lược giữa các ý kiến ​​để đưa mã gốc trong một tập tin thư viện (gọi nó là LibFile) và sau đó đặt một initializer tĩnh:

static { System.loadLibrary("LibFile"); } 

trong tuyên bố lớp học. Khi lớp được tải và được khởi tạo, việc triển khai mã gốc cần thiết cần thiết cho các phương thức gốc sau đó sẽ được tải .

Nếu phương pháp này được gọi là hơn một lần với tên cùng một thư viện, các cuộc gọi thứ hai và tiếp theo là bỏ qua.

+0

Đúng - bạn hiểu rồi :) –

+1

Điều này có đúng với System.load không? Các tài liệu không chỉ định một trong hai cách. –

+0

Có. Điều này cũng đúng đối với System.load. –

0

Tôi chắc rằng mọi cuộc gọi tiếp theo tải thư viện đã tải đều không có hiệu lực [cần dẫn nguồn].

Điều này đã được xác minh trong mã nguồn lớp học ClassLoader, nhưng tôi vẫn đang cố gắng tìm một nguồn tốt cho việc này.

0

Tạo một lớp singleton mà tải "JNI" chỉ trong thời gian đó là instantiation đầu tiên, và gọi singleton này trong class1 và Class2 thay vì System.loadLibrary ("JNI")

2

Từ JavaDocs -

Nếu phương thức này được gọi nhiều lần với cùng tên thư viện, cuộc gọi thứ hai và sau đó sẽ bị bỏ qua.