2011-10-30 26 views
6

dự án java appengine của tôi không giữ bất kỳ nhà nước giữa các yêu cầu trừ những ứng dụng sau đây của Memcache:Danh sách kiểm tra cho thread-safe java trên appengine

  • làm thành khách quan sử dụng memcache để cache kho dữ liệu được
  • tôi sử dụng memcache như một cách để thực hiện các nhiệm vụ dọn dẹp hàng loạt sau nhiều yêu cầu (ví dụ: if (the memcache doesn't think a cleanup task is already running) schedule another cleanup task).

Tôi không có/tài liệu tham khảo tĩnh toàn cầu đối với bất kỳ đối tượng, ngoại trừ:

  • Người dùng thực hiện được giữ trong một đối tượng static ThreadLocal<User>. Điều này có nghĩa là mỗi yêu cầu sẽ nhận được bản sao của một Người dùng, đúng không?
  • Tôi có một lớp xử lý tất cả thao tác dữ liệu và một cá thể được giữ như một loại biến toàn cục trong đối tượng static DataCoordinator.

Tôi cần làm gì để đảm bảo an toàn cho chuỗi của mình? Tôi có cần phải ném một từ khóa synchronized vào mọi khai báo phương thức trong việc triển khai DataCoordinator của tôi, vì nhiều luồng có thể truy cập vào nó không? Có đúng là đối tượng ThreadLocal<User> sẽ luôn tạo đối tượng riêng biệt User cho mỗi chuỗi sao cho mỗi yêu cầu sẽ được xác thực riêng biệt?

Tôi là tổng số người mới tham gia tư duy an toàn cho chủ đề. Tôi nên đọc gì?

Cảm ơn bạn đã được trợ giúp và xin lỗi vì thiếu tính đặc hiệu.

+0

Bạn có bất cứ lớp singlton, nơi bạn luôn có được một tham chiếu đến cùng một ví dụ thông qua một .getInstance()? Nếu vậy, nhiều yêu cầu song song được thực thi trong các luồng khác nhau bên trong cùng một cá thể/cá thể có thể nhận được tham chiếu đến cùng một đối tượng .... và sau đó lớp trong việc sử dụng nó hoặc sửa đổi các biến mẫu. –

Trả lời

7

Điều đầu tiên bạn cần lưu ý là công cụ ứng dụng có thể sao chép ứng dụng của bạn trên nhiều máy chủ. Điều đó có nghĩa là các biến tĩnh của bạn sẽ là duy nhất trên một máy chủ. Do đó, DataCoordinator của bạn sẽ chỉ điều phối truy cập dữ liệu trên một máy chủ duy nhất. Vì vậy, nếu bạn cần dữ liệu chung cho tất cả các máy chủ đang chạy ứng dụng của bạn, bạn nên luôn sử dụng kho dữ liệu cho cơ chế đó (hoặc cơ chế phiên HTTP gae trong một số trường hợp).

Về an toàn chủ đề của DataCoordinator: Bạn chỉ cần đồng bộ hóa các phương pháp của điều phối viên này nếu các phương pháp này không được thực hiện theo cách an toàn. Ví dụ, bạn không cần phải đồng bộ hóa bất kỳ phương thức nào không truy cập bất kỳ dữ liệu cá thể/tĩnh nào mà chỉ lấy dữ liệu từ kho dữ liệu. Nếu các phương thức truy cập dữ liệu chung/dữ liệu tĩnh có thể thay đổi (đồng thời được viết), bạn có thể đồng bộ hóa trên một màn hình đặc biệt cho dữ liệu được truy cập trong hầu hết các trường hợp thay vì đồng bộ hóa trên toàn bộ điều phối viên.

Được sử dụng để lưu trữ mã thông báo xác thực: Bạn có thể thực hiện điều đó nó cho chủ đề đó. Có nghĩa là tốt nhất là đảm bảo rằng biến được đặt cho mỗi luồng và bạn có thể sử dụng khóa try - finally sau khi đặt nó mà cuối cùng sẽ xóa dữ liệu xác thực sau khi sử dụng. Tại sao? Điều tồi tệ nhất có thể xảy ra nếu không sẽ là một chuỗi thuộc về yêu cầu của người dùng B vẫn có một mã thông báo người dùng A. Đó là vì các chủ đề được sử dụng trong máy chủ ứng dụng thường được gộp giữa các yêu cầu thay vì cleand up và tái tạo.

Tôi không thể nói gì về memcache vì tôi chưa sử dụng.

Thông thường, bạn phải lưu ý rằng mọi yêu cầu web (servlet/JSP/...) có thể được máy chủ xử lý đồng thời.Vì vậy, bất kỳ tài nguyên chia sẻ có thể thay đổi nào được truy cập bởi các luồng đó phải được đồng bộ hóa hoặc được triển khai theo cách an toàn.

Có thể http://download.oracle.com/javase/tutorial/essential/concurrency/ là điểm khởi đầu tốt để đọc nó.

+0

Tôi không cần datacoordinator là như nhau cho tất cả các chủ đề, tôi chỉ cần nó để không mess bất cứ điều gì lên khi nó xảy ra để được truy cập bởi hai chủ đề cạnh tranh. Cảm ơn câu trả lời - Tôi sẽ xem hướng dẫn này. –

3

Nếu bạn có các lớp đơn, thì chỉ ONE cá thể sẽ được tạo/sử dụng bởi mã của bạn trên mỗi máy ảo/Instance được tạo.

Một tham chiếu đến singleton này có thể được lấy từ:
- hai yêu cầu tuần tự làm cái khác được phục vụ bởi cùng một ví dụ (phụ thuộc vào thiết lập của bạn trong bao lâu họ ở lại xung quanh, hoặc nếu một trường dành riêng đang chạy)
- hai yêu cầu song song đang chạy trong các chuỗi riêng biệt trên cùng một trường hợp NẾU bạn đã đặt chủ đề thành đúng.

Tôi đã viết và kiểm tra mã để xác nhận điều này cho chính mình và được triển khai và thử nghiệm. Nếu mã trong một yêu cầu sử dụng singleton để sửa đổi một trong các biến thành viên của nó, thì nó được sửa đổi cho yêu cầu khác chạy song song.

Tất cả thực sự hợp lý, khi bạn tìm ra tuổi thọ của máy ảo và có bao nhiêu chủ đề (chỉ 1 hoặc nhiều chuỗi) được sử dụng để phân phát các yêu cầu đến.

Ngoài ra, các biến hệ thống có thể được sửa đổi trong mã trong một yêu cầu và đọc trong một yêu cầu khác ... một cách thứ hai hai yêu cầu/chủ đề song song có thể tương tác.

Xem thêm chi tiết về vấn đề này trong bài viết trên blog của tôi trên multi-threading trong GAE/J ở đây:
http://devcon5.blogspot.com/2012/09/threadsafe-in-appengine-gaej.html

Các vấn đề liên quan