Masterfield

A Masterfield Oktatóközpont szakmai blogja. Minden, ami a tanfolyamokról kimaradt

Friss topikok

  • gyuria: Na végre, már nagyon vártam Már annyi téma összejött, hogy egy jó darabig biztos kitart :) (2008.10.24. 08:04) Elindultunk

Linkblog

Java holtpont vizsgálata thread dump segítségével - 3. rész

2008.09.17. 12:36 | gbujdoso | Szólj hozzá!

Címkék: java collection jvm stack thread holtpont dump masterfield thread dump hashtable deadlock util

És még tovább menve...

Java stack information for the threads listed above:

===================================================

"Thread-1":

        at java.util.Hashtable.size(Hashtable.java:206)

        - waiting to lock <0x24100158> (a java.util.Hashtable)

        at java.util.Hashtable.equals(Hashtable.java:742)

        - locked <0x24100180> (a java.util.Hashtable)

        at Bug$1.run(Bug.java:16)

        at java.lang.Thread.run(Thread.java:619)

"Thread-0":

        at java.util.Hashtable.get(Hashtable.java:333)

        - waiting to lock <0x24100180> (a java.util.Hashtable)

        at java.util.Hashtable.equals(Hashtable.java:755)

        - locked <0x24100158> (a java.util.Hashtable)

        at Bug$1.run(Bug.java:16)

        at java.lang.Thread.run(Thread.java:619)

 

...eljutunk a két holtpontot okozó függvényhez:

 

/**

 * Returns the number of keys in this hashtable.

 *

 * @return  the number of keys in this hashtable.

 */

public synchronized int size() {

      return count;

}

 

/**

 * Returns the value to which the specified key is mapped,

 * or {@code null} if this map contains no mapping for the key.

 *

 * <p>More formally, if this map contains a mapping from a key

 * {@code k} to a value {@code v} such that {@code (key.equals(k))},

 * then this method returns {@code v}; otherwise it returns

 * {@code null}.  (There can be at most one such mapping.)

 *

 * @param key the key whose associated value is to be returned

 * @return the value to which the specified key is mapped, or

 *         {@code null} if this map contains no mapping for the key

 * @throws NullPointerException if the specified key is null

 * @see     #put(Object, Object)

 */

public synchronized V get(Object key) {

      Entry tab[] = table;

      int hash = key.hashCode();

      int index = (hash & 0x7FFFFFFF) % tab.length;

      for (Entry<K,V> e = tab[index] ; e != null ; e = e.next) {

            if ((e.hash == hash) && e.key.equals(key)) {

                  return e.value;

            }

      }

      return null;

}

 

Tehát van egy synchronized equals függvényünk, amiben van két további lokális synchronized függvényhívás. Ez bizony holtpont! Hogy pontosan megértsük létrejöttét először nézzük meg mit is jelent, ha egy függvényt synchronized kulcsszóval deklarálunk. Amikor egy objektum adott példányán valaki meghívja ezt a függvényt, akkor ehhez az objektumhoz létrejön egy lock, azaz zárolva lesz. Ilyen esetben, ha egy másik szál egy másik (vagy éppen ugyanazt a) szinkronizált metódusát szeretné hívni, akkor várnia kell a végrehajtással. A dumpban látszik, hogy a két szál kölcsönösen a másik szál által korábban létrehozott zár feloldására vár.

"Thread-1":

        at java.util.Hashtable.size(Hashtable.java:206)

        - waiting to lock <0x24100158> (a java.util.Hashtable)

        at java.util.Hashtable.equals(Hashtable.java:742)

        - locked <0x24100180> (a java.util.Hashtable)

        at Bug$1.run(Bug.java:16)

        at java.lang.Thread.run(Thread.java:619)

"Thread-0":

        at java.util.Hashtable.get(Hashtable.java:333)

        - waiting to lock <0x24100180> (a java.util.Hashtable)

        at java.util.Hashtable.equals(Hashtable.java:755)

        - locked <0x24100158> (a java.util.Hashtable)

        at Bug$1.run(Bug.java:16)

        at java.lang.Thread.run(Thread.java:619)

 

Érdemes elgondolkodnunk a hiba leírásában szereplő tanulságon:

"Never call foreign code while holding a lock."

Azaz egy szinkronizált függvényhívásból soha ne hívjunk ki más függvénybe (az adott objektumon belül).

 

Egy lehetséges javítása a problémának, hogy a size és get metódusokban lévő kódot bemásoljuk közvetlenül az equals függvény megfelelő helyére. Ilyen esetben szálanként csak egy-egy lockunk lesz, ami így is elég.

 

Amennyiben bárkinek további helyes megoldási javaslata van és azt kidolgozva elküldi az „info kukac masterfield.hu” címre 10% kedvezményt kap a Masterfield Oktatóközpont bármelyik tanfolyamának árából.

 

A fenti deadlockhoz hasonlóval mindannyian találkoztunk már, csak esetleg nem is tudtunk róla, hogy a háttérben ezen hibás működés áll. Mindenki találkozott már lefagyott számítógéppel és bármit csinált nem bírta kimozdítani ebből a holtpontból. Ahogy azt a bevezetőben említettem nagyon sok programozó nincs is tisztában a holtpontot előidéző helyzetekkel és nem tudja, hogy amit leír az potenciálisan tartalmazhat-e ilyen pontot.

Véleményem szerint az informatika egyik jelenlegi, nagyon fontos és megoldásra váró kihívása ezen holtpontok minél egyszerűbb felismerése még a program készítésének szakaszában. Illetve az operációs és egyéb futtató keretrendszerek (VM-ek) felkészítése a holtpontok felismerésére és feloldására.

 

A bejegyzés trackback címe:

https://masterfield.blog.hu/api/trackback/id/tr31745340

Kommentek:

A hozzászólások a vonatkozó jogszabályok  értelmében felhasználói tartalomnak minősülnek, értük a szolgáltatás technikai  üzemeltetője semmilyen felelősséget nem vállal, azokat nem ellenőrzi. Kifogás esetén forduljon a blog szerkesztőjéhez. Részletek a  Felhasználási feltételekben és az adatvédelmi tájékoztatóban.

Nincsenek hozzászólások.
süti beállítások módosítása