2010-05-18 6 views
5

Mam kolekcję instancji BufferedImage, jednego głównego obrazu i niektórych podobrazi utworzonych przez wywołanie getSubImage na głównym obrazie. Podobrazie nie zachodzą na siebie. Wprowadzam także modyfikacje do subimage i chcę podzielić to na wiele wątków, po jednym na subimage.Bezpieczne, aby zaktualizować oddzielne regiony BufferedImage w osobnych wątkach?

Z mojego zrozumienia jak BufferedImage, Raster i DataBuffer pracy, to powinno być bezpieczne, ponieważ:

  • Każda instancja BufferedImage (i jej odpowiednia WritableRaster i SampleModel) jest dostęp tylko z jednego wątku.
  • Wspólna ColorModel jest niezmienna
  • DataBuffer nie ma pola, które mogą być modyfikowane (jedyną rzeczą, która może zmienić to elementy tablicy podkładowej.)
  • Modyfikowanie rozłączne segmenty tablicy w oddzielnych wątków jest bezpieczny.

Jednak nie mogę znaleźć niczego w dokumentacji, która mówi, że zdecydowanie jest to bezpieczne. Czy mogę założyć, że jest bezpieczny? Wiem, że można pracować na kopiach dziecka, ale wolałbym tego uniknąć z powodu ograniczeń pamięci.

Czy możliwe jest wykonanie operacji bez zabezpieczeń, bez kopiowania regionów obrazu macierzystego?

Odpowiedz

4

Pan spojrzał w użyciu JAI zarządzać 'wyświetlać osobno' jak płytki? Wydaje się, że lepiej wykorzystać zasoby, jeśli nie musisz trzymać się oryginalnej instancji BufferedImage, jak również jej instancji SubImage BufferedImage. Informacje na temat JAI można znaleźć tutaj: JAI README

Istnieje klasa TiledImage, która implementuje interfejs RenderedImage (dając mu wspólny przodek z BufferedImage). Zgodnie z dokumentacją JAI:

Zastosowanie płytek ułatwia również korzystanie z wielu wątków do obliczeń. Wcześniej przydzielone płytki można również ponownie wykorzystać do zapisania pamięci .

Korzystanie z jednej z tych wersji renderowania jest często preferowane z użyciem obrazu buforowanego, ponieważ bufor obrazu zachowuje migawkę obrazu w pamięci dla całego obrazu.JAI używa łańcucha renderowania i może odtworzyć płytki zgodnie z potrzebami, aby dopasować ograniczenia pamięci.

1

nie znalazłem żadnego wyraźnego dowodu bezpieczeństwa gwintu BufferedImage, ale prawdopodobnie może rozwiązać Twój problem następny sposób:

Zamiast jednoczesnego przetwarzania wyświetlać osobno przez różnych pracowników, staramy się przetwarzać wiele obrazów w sposób, w jaki każdy pracownik zużywa różne podobrazie tego samego obrazu. Ten sam pracownik będzie przetwarzał podobrazi tego samego obrazu, ale sekwencyjnie.

Twoi pracownicy będą zajęci, dopóki nie będzie mniej zdjęć niż pozostali robotnicy.

Przywróć ten problem:

 
     W1  W2  W3 
Img1 |-------|-------|-------| 
     W1  W2  W3 
Img2 |-------|-------|-------| 
Do:

 
     W1  W1  W1 
Img1 |-------|-------|-------| 
     W2  W2  W2 
Img2 |-------|-------|-------| 
+0

Wtedy nie ma żadnej korzyści dla podziału obrazu. – finnw

+0

Wolałbym kontynuować przetwarzanie podobrazów pojedynczego obrazu w wielu wątkach, aby zmniejszyć opóźnienie. Nawet jeśli okaże się, że wymaga to skopiowania podobrazów. – finnw

2

To dobra analiza i brzmi dla mnie poprawnie. Brak danych wspólnych, więc dostęp równoległy powinien być w porządku. Jednak musisz mieć jakąś gwarancję, aby być pewnym, więcej niż wykształcone przypuszczenie, że powinno działać. Nawet jeśli znajdziesz stwierdzenie "BufferedImage jest przeznaczone do jednoczesnego korzystania" - nie ma gwarancji, że tak jest w praktyce.

Aby być pewnym, jak możesz być, możesz napisać test równoczesnej jednostki, używając ConTest. Współbieżna wiązka testowa instrumentuje twój kod i wstrzykuje sztucznie wywołane przełączniki kontekstowe, aby ujawnić błędy współbieżności. Spowoduje to przetestowanie kodu BufferedImage i własnego kodu, dzięki czemu możesz mieć wysoki poziom pewności, że jest bezpieczny dla wątków.