Samtidighet, blokkeringskøer (Java 7) - 1

"Hei, Amigo!"

"Hei, Kim!"

"I dag skal jeg fortelle deg om samtidighet."

" Concurrency er et Java-klassebibliotek som inkluderer spesialklasser som er optimert for arbeid fra flere tråder. Dette er et veldig interessant og omfattende emne. Men i dag skal vi bare få en introduksjon. Pakken heter java.util. samtidig pakke. Jeg skal fortelle deg om et par interessante klasser."

" Atomtyper. "

"Du vet allerede at selv count++ ikke er en trådsikker operasjon. Når en variabel økes med 1, finner faktisk tre operasjoner sted. Som et resultat kan det oppstå en konflikt når variabelen endres."

"Ja, Ellie fortalte meg for ikke lenge siden:"

Tråd 1 Tråd 2 Resultat
register1 = count;
register1++;
count = register1;
register2 = count;
register2++;
count = register2;
register1 = count;
register2 = count;
register2++;
count = register2;
register1++;
count = register1;

"Akkurat. Så la Java til datatyper for å utføre disse operasjonene som én, dvs. atomært (et atom er udelelig)."

"For eksempel har Java AtomicInteger, AtomicBoolean, AtomicDouble , etc."

«Anta at vi må lage en «teller»-klasse:»

Eksempel
class Counter
{
 private int c = 0;

 public void increment()
 {
  c++;
 }

 public void decrement()
 {
  c--;
 }

 public int value()
 {
  return c;
 }
}

"Hvordan vil du gjøre gjenstander av denne klassen trådsikre?"

"Vel, jeg ville gjøre alle metodene synkronisert og være ferdig med det:"

Eksempel
class synchronized Counter
{
 private int c = 0;

 public synchronized void increment()
 {
  c++;
 }

 public synchronized void decrement()
 {
  c--;
 }

 public synchronized int value()
 {
  return c;
 }
}

"Bra arbeid. Men hvordan ville det sett ut hvis vi brukte atomtyper:"

Eksempel
class AtomicCounter
{
 private AtomicInteger c = new AtomicInteger(0);

 public void increment()
 {
  c.incrementAndGet();
 }

 public void decrement()
 {
  c.decrementAndGet();
 }

 public int value()
 {
  return c.get();
 }
}

"Klassen din og klassen min fungerer begge på samme måte, men klassen med et AtomicInteger fungerer raskere."

"Vel, er det en liten forskjell?"

"Ja. Basert på min erfaring anbefaler jeg alltid å lede med synkronisert. Først når all applikasjonskoden er skrevet og optimaliseringsprosessen har begynt bør du begynne å skrive om koden for å bruke atomtypene. Men i alle fall ville jeg ha deg å vite at slike typer finnes. Selv om du ikke bruker dem aktivt, er det alltid en sjanse for at du kommer inn i kode der de brukes."

"Jeg er enig. Det gir mening."

"La du forresten merke til at atomtypene ikke er uforanderlige ? I motsetning til standard Integer -klassen, inneholder AtomicInteger metoder for å endre dens interne tilstand."

"Skjønner det. Akkurat som String og StringBuffer ."

"Ja, noe sånt."

" Trådsikre samlinger. "

"Som et eksempel på en slik samling, kan jeg presentere ConcurrentHashMap. Hvordan vil du gjøre HashMap trådsikker?"

"Gjøre alle metodene synkronisert?"

"Jada, men forestill deg nå at du har en slik SynchronizedHashMap, og dusinvis av tråder som har tilgang til den. Og hundre ganger i sekundet legges en ny oppføring til kartet, og i prosessen låses hele objektet for lesing og skriving."

"Vel, dette er standardmetoden. Hva kan du gjøre?"

"Javas skapere kom opp med noen kule ting."

"Først lagrer de data i et ConcurrentHashMap i en enkelt blokk, men deler det inn i deler som kalles "buckets". Og når noen endrer data i et ConcurrentHashMap, låser vi bare bøtten som er tilgjengelig, i stedet for hele objektet. I andre ord, mange tråder kan endre objektet samtidig."

"For det andre, husker du at du ikke kan iterere over elementene i listen/kartet og endre listen samtidig? Slik kode vil gi et unntak:"

Ikke iterer over elementene i en samling i en løkke og endre den samtidig
HashMap<String, Integer> map = new HashMap<String, Integer>();

for (String key: map.keySet())
{
 if (map.get(key) == 0)
  map.remove(key);
}

"Men i ConcurrentHashMap kan du:"

Ikke iterer over elementene i en samling i en løkke og endre den samtidig."
ConcurrentHashMap<String, Integer> map = new ConcurrentHashMap<String, Integer>();

for (String key: map.keySet())
{
 if (map.get(key) == 0)
  map.remove(key);
}

"Den samtidige pakken har mange fordeler. Vi trenger bare å forstå disse klassene veldig godt for å kunne bruke dem."

"Jeg skjønner. Takk, Kim. Dette er virkelig interessante klasser. Jeg håper at jeg en dag vil mestre dem som en virtuos."