Synchronizacja

Po dostaniu elementów tablicy za pomocą wywołania Get< Type>ArrayElements należy pomyśleć o synchronizacji.

Niezależnie od tego, czy dane są zaczepione, czy nie, dwa podmioty są zaangażowane w dostęp do danych:
  • Kod Java™ , w którym jednostka danych jest zadeklarowana i używana
  • Kod rodzimy, który uzyskuje dostęp do danych za pośrednictwem JNI

Te dwa obiekty są prawdopodobnie oddzielnymi wątkami, w których występuje rywalizacja o wielkość liter.

Rozważmy następujący scenariusz w kopiowaniu implementacji JNI:
  1. Program Java tworzy dużą tablicę i częściowo wypełnia je danymi.
  2. Program Java wywołuje rodzimą funkcję zapisu w celu zapisania danych w gnieździe.
  3. Rodzimy JNI, który implementuje interfejs write() , wywołuje funkcję GetByteArrayElements.
  4. GetByteArrayElements kopiuje zawartość tablicy do buforu i zwraca ją do rodzimego.
  5. Rodzimy JNI rozpoczyna zapisywanie regionu z buforu do gniazda.
  6. Podczas gdy wątek jest zajęty pisaniem, inny wątek (Java lub rodzimy) uruchamia i kopiuje więcej danych do tablicy (poza regionem, który jest zapisywany).
  7. Rodzimy JNI kończy zapisywanie regionu w gnieździe.
  8. Rodzime wywołania JNI ReleaseByteArrayElements z trybem 0 wskazują, że operacja została zakończona z tablicą.
  9. Maszyna VM, widząc tryb 0, kopiuje całą zawartość bufora do tablicy i nadpisuje dane, które zostały zapisane przez drugi wątek.

W tym konkretnym scenariuszu kod działa z maszyną JVM przypinania. Ponieważ każdy wątek zapisuje tylko swój własny bit danych, a opcja trybu jest ignorowana, rywalizacja nie występuje. Ten scenariusz jest kolejnym przykładem kodu, który nie jest ściśle zapisany w specyfikacji działa z jedną implementacją maszyny JVM, a nie z inną implementacją. Chociaż ten scenariusz obejmuje kopiowanie elementów tablicy, dane przypięte mogą być również uszkodzone, gdy dwa wątki uzyskują dostęp do niego w tym samym czasie.

Należy zachować ostrożność podczas synchronizowania dostępu do elementów tablicy. Interfejsów JNI można używać w celu uzyskania dostępu do regionów tablic Java i łańcuchów w celu zmniejszenia problemów związanych z tym typem interakcji. W scenariuszu wątek, który zapisuje dane, zapisuje w swoim regionie. Wątek, który odczytuje dane, odczytuje tylko jego własny region. Ta metoda działa z każdą implementacją JNI.