2011-07-04 32 views
33

SwingUtilities.invokeLater làm gì? Nó chỉ trì hoãn việc thực thi một khối mã bên trong phương thức run của nó? Sự khác nhau giữa việc gọi một hành động trong hàm invokeLater hoặc đơn giản gọi nó là gì ở cuối chuỗi mà chúng ta muốn được thực thi? Bất cứ ai có thể giúp tôi với những gì thực sự chức năng invokeLater làm gì?SwingUtilities.invokeLater làm gì?

+0

Xem thêm http://stackoverflow.com/questions/5780936/java-eventqueue-why-should-everything-be-in-invokelater-method cho nền (nền có liên quan, nhưng không trùng lặp). –

+0

Tra cứu Swing EDT trên Google. –

Trả lời

20

Như câu trả lời khác đã nói, nó thực hiện Runnable của bạn trên chuỗi gửi sự kiện AWT. Nhưng tại sao bạn muốn làm điều đó? Bởi vì các cấu trúc dữ liệu Swing không an toàn cho luồng, do đó, để cung cấp cho các lập trình viên một cách dễ dàng đạt được để ngăn chặn truy cập đồng thời, các nhà thiết kế Swing đã đặt ra quy tắc rằng tất cả các mã truy cập chúng phải chạy trên cùng một luồng. Điều đó xảy ra tự động cho mã bảo trì sự kiện và xử lý sự kiện, nhưng nếu bạn đã bắt đầu một hành động dài hạn - trên một chuỗi mới, tất nhiên - làm cách nào bạn có thể báo hiệu tiến trình hoặc sự hoàn thành của nó? Bạn phải sửa đổi một điều khiển Swing, và bạn phải làm điều đó từ thread sự kiện-dispatching. Do đó invokeLater.

+0

OOH! vì vậy đây là cách bạn có thể làm luồng đơn không đồng bộ trong java! Thật kỳ lạ là nó phải được đi kèm với bộ công cụ "Windowing", có vẻ hơi lệch. – Dmitry

+2

@ Dmitry Đó là một cách thú vị để nhìn vào nó. Java không cung cấp hỗ trợ cấp ngôn ngữ cho luồng đơn (không có bất kỳ ngôn ngữ nào?). Vì vậy, một khuôn khổ yêu cầu nó phải cung cấp các tính năng để hỗ trợ nó và đặt ra các quy tắc cho lập trình viên khách hàng để sử dụng nó một cách chính xác. Đây không phải là "Cách Java để làm điều đó", thay vào đó là một cách để làm điều đó trong Java. –

8

Nó sẽ chạy đoạn mã trên chuỗi AWT. Cho phép bạn sửa đổi GUI từ các chủ đề khác.

Từ Docs:

Nguyên nhân doRun.run() được thực thi không đồng bộ trên các sự kiện AWT dispatching thread. Điều này sẽ xảy ra sau khi tất cả các sự kiện AWT đang chờ xử lý đã được xử lý . Phương pháp này nên được sử dụng khi một chuỗi ứng dụng cần phải cập nhật GUI.

2

đó là sẽ được Bình luận, nhưng trông giống như như còn như ..., những thứ chỉ là cơ bản

1/tạo EDT riêng để cập nhật chính xác cho GUI, f.e. nếu bạn đang thực hiện một số mã bằng cách sử dụng đồng bằng vani Thread, java.util.Timer, Executor .. hơn here

2/giúp với bộ Focus đến JComponents iof có một số Listeners bởi vì nếu là có f.e. DocumentListener thì bạn khó có thể thiết lập Focus với mong muốn JComponents hành đang

3/chậm trễ chặn và di chuyển mà cho đến tận cùng EDT

2

Như đã lưu ý, invokeLater cho phép bạn gọi các phương thức trong lớp xoay khi bạn đang an toàn không chạy trên EventQueue để bắt đầu. Tuy nhiên, bạn có thể đơn giản hóa mã và cuộc sống của mình bằng cách truy cập các trường và lớp khác chỉ từ EventQueue. Họ có thể làm việc với swing và mỗi khác mà không có tất cả các phức tạp của đa luồng. Nếu bạn đã bắt đầu một luồng khác, hãy sử dụng InvokeLater để quay lại EventQueue nhanh nhất có thể và giảm thiểu số lượng trường phải được đồng bộ hóa hoặc bảo vệ khác.

Nếu bạn cần tận dụng tối đa nhiều lõi, bạn sẽ phải giảm việc sử dụng EventQueue và bạn sẽ phải trả một mức giá lớn về độ phức tạp.

1

Lưu ý rằng bạn cuối cùng nhận được cuộc gọi đến phương thức doRun.run() của bạn cho mỗi thời gian bạn gọi invokeLater (doRun). Vì vậy, nếu bạn gọi nó mười lần trước khi chuỗi sự kiện có cơ hội để thực hiện xử lý của nó, thì bạn có thể nhận được mười cuộc gọi liên tiếp tới doRun.run().