Middle
Mis on synchronized plokk Java-s ja millised probleemid võivad selle kasutamisel tekkida?
sobes.tech AI
Vastus AI-lt
Java synchronized blokk i izmanto, lai nodrošinātu piekļuves sinhronizāciju kopīgam resursam starp vairākiem pavedieniem. Tas garantē, ka tikai viens pavediens var izpildīt kodu blokā vienlaikus.
Synchronized bloka struktūra:
synchronized (monitora_objekts) {
// Kritiskā sekcija
// Šeit tiek veiktas operācijas ar kopīgo resursu
}
monitora_objekts: jebkurš objekts, kas darbojas kā monitors (lock). Pavedieni, kas mēģina ieietsynchronizedblokā ar to pašu monitora objektu, tiks bloķēti līdz brīdim, kad pašreizējais pavediens izies no bloka.
Iespējamās problēmas, izmantojot synchronized:
- Aizsargājoša bloķēšana (Deadlock): Divi vai vairāki pavedieni gaida resursa atbrīvošanu, kas ir aizņemts ar citu pavedienu, kas noved pie programmas iesaldēšanas. Tas var notikt, ja pavedieni mēģina iegūt bloķējumus dažādā secībā.
- Veiktspējas samazināšanās: Synchronized bloķē citu pavedienu izpildi, kas gaida piekļuvi monitoram, kas var palēnināt paralēlo lietojumprogrammu darbību.
- Neatbilstošība dažiem scenārijiem:
synchronizednodrošina ekskluzīvu piekļuvi. Dažos gadījumos var būt nepieciešama elastīgāka piekļuves pārvaldība (piemēram, lasīšana ar vairākiem pavedieniem vienlaikus, rakstīšana vienā pavedienā). - Grūti diagnosticēt: Sinhronizācijas problēmas var būt neizskaidrojamas un grūti reproducējamas un novēršamas.
Vairāk par aizsargājošo bloķēšanu:
class Resursi {
private Object lock1 = new Object();
private Object lock2 = new Object();
public void metode1(Resursi cits) {
synchronized (lock1) {
try {
Thread.sleep(100); // Imitācija darba
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println(Thread.currentThread().getName() + " ieguva lock1");
synchronized (cits.lock2) {
System.out.println(Thread.currentThread().getName() + " ieguva cita lock2");
}
}
}
public void metode2(Resursi cits) {
synchronized (lock2) {
try {
Thread.sleep(100); // Imitācija darba
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println(Thread.currentThread().getName() + " ieguva lock2");
synchronized (cits.lock1) {
System.out.println(Thread.currentThread().getName() + " ieguva cita lock1");
}
}
}
}
public class DeadlockExample {
public static void main(String[] args) {
Resursi r1 = new Resursi();
Resursi r2 = new Resursi();
new Thread(() -> r1.metode1(r2), "Pavedien-1").start();
new Thread(() -> r2.metode2(r1), "Pavedien-2").start();
}
}
Šajā piemērā Pavedien-1 mēģina iegūt lock1 r1 un pēc tam lock2 r2. Pavediens-2 mēģina iegūt lock2 r2 un pēc tam lock1 r1. Ja viņi iegūst pirmās bloķēšanas vienlaikus, rodas aizsargājoša bloķēšana.