Navigacija
Lista poslednjih: 16, 32, 64, 128 poruka.

Dodavanje zapisa u fajl kroz vise thread-ova

[es] :: Java :: Dodavanje zapisa u fajl kroz vise thread-ova

[ Pregleda: 2857 | Odgovora: 5 ] > FB > Twit

Postavi temu Odgovori

Autor

Pretraga teme: Traži
Markiranje Štampanje RSS

googol

Član broj: 181890
Poruke: 6
85.94.121.*



Profil

icon Dodavanje zapisa u fajl kroz vise thread-ova20.05.2008. u 09:58 - pre 193 meseci
Evo ovako, imam situaciju da imam N threadova ciji je zadatak da prime objekat tipa "Kvadrat" i u jedan fajl , npr. c:\podaci.txt upisu njegove mjere.

Ja sam uradio sljedece, kreirao sam klasu Kvadrat:

Code:

public class Kvadrat 
{
    
int visina, sirina;

public Kvadrat(int visina, int sirina) 
{
    this.visina = visina;
    this.sirina = sirina;
}

public int getVisina() 
{
    return visina;
}

public int getSirina() 
{
    return sirina;
}
}


zatim klasu ObradaKvadrata koja implementira Runnable

Code:

public class ObradaKvadrata implements Runnable
{
    
    Kvadrat kvadrat;

    public ObradaKvadrata(Kvadrat kvadrat) 
    {
        this.kvadrat=kvadrat;
    }
    
    public void obradi()
    {
            new UpisPodatakaUFajl().upisiPodatke(kvadrat);   
               
    }

    @Override
    public void run() 
    {
        obradi();
        
    }
}

i koja poziva metodu upisiPodatke a koja pripada klasi UpisPodatakaUFajl :

Code:

import java.io.BufferedWriter;
import java.io.File;
import java.io.FileWriter;
import java.io.IOException;

public class UpisPodatakaUFajl 
{
    public synchronized void upisiPodatke(Kvadrat kvadrat)
  {
   boolean pf;
   File fajl =new File("c:\\podaci.txt");
   pf = fajl.exists(); 
   if (pf == false)
   { 
       try { 
             fajl.createNewFile();
             BufferedWriter out = new BufferedWriter(new FileWriter(fajl, true)); 
             out.write("Visina: " + Integer.toString(kvadrat.getVisina()) + "  , Sirina: " + Integer.toString(kvadrat.getSirina()) + "\n");
             out.close(); 
           } 
       catch (IOException e) 
       { 
       System.out.println("Greska pri kreiranju/upisu u fajl \"podaci\"");  
       }
   }
   else if (pf == true)
   {
       try { 
             BufferedWriter out = new BufferedWriter(new FileWriter(fajl, true)); 
             out.write("Visina: " + Integer.toString(kvadrat.getVisina()) + "  , Sirina: " + Integer.toString(kvadrat.getSirina()) + "\n");
             out.close(); 
           } 
       catch (IOException e) 
       { 
           System.out.println("Greska pri upisu u fajl \"podaci\"");  
       }
   }
   
  }  
    }

koja ima zadatak da upise podatke u fajl c:\podaci.txt , i da ga kreira prvo ako ne postoji...

Sve se ovo pokrece sa kodom:
Code:

Public class Main
{

public static void main(String[] args)
{
int i;
        for(i=1;i<=10;i++)
        {
        Kvadrat k = new Kvadrat(i,i);
            new Thread(new ObradaKvadrata(k)).start();
        }
}

}

Problem je sto mi nikako ne moze normalno upisati svih 10 kvadrata. Stalno izbacuje exception ili ako ne izbaci gresku, onda upise samo nekoliko kvadrata i/ili "0" umjesto nekog od njih. Ima li ko ideju zasto je to tako?
 
Odgovor na temu

NeoDesign
Vladimir Ćetković
Software developer
Beograd

Član broj: 16257
Poruke: 138
*.static.sbb.rs.

ICQ: 23348136
Sajt: www.codesessions.com


+2 Profil

icon Re: Dodavanje zapisa u fajl kroz vise thread-ova20.05.2008. u 14:01 - pre 193 meseci
Mislim da je najveci problem u tome sto sam fajl nije sinhronizovan i da vise niti pristupa istom toku. Pokusaj da ili fajl ili tok (BufferedWriter) ucinis sinhronizovanim (da druge niti cekaju da se oslobodi). Pogledaj sun-ov sajt za primer.
Arthur C. Clarke - "Any sufficiently advanced technology is indistinguishable from magic."
 
Odgovor na temu

googol

Član broj: 181890
Poruke: 6
85.94.121.*



Profil

icon Re: Dodavanje zapisa u fajl kroz vise thread-ova20.05.2008. u 14:15 - pre 193 meseci
Hvala na odgovoru.

pa i ja pretpostavljam ( ustvari, poprilicno sam siguran ) da je do toga, zato sam stavio da je metoda upisiPodatke synchronized

Mada, kada sada razmislim - trebao sam mozda izvesti da svi threadovi pristupaju istoj instanci klase UpisPodatakaUFajl , tj. jednoj istoj metodi...ovako svaki otvara

Code:
 new UpisPodatakaUFajl().upisiPodatke(kvadrat); 


Slazete se?

Neko drugo misljenje ?
 
Odgovor na temu

grizzly
Beograd

Član broj: 7978
Poruke: 262



+4 Profil

icon Re: Dodavanje zapisa u fajl kroz vise thread-ova20.05.2008. u 16:44 - pre 193 meseci
Imas u tutorijalu za niti neko objekat chubby nesto nesto, koji je kolekcija ok okje se kreira jedan objekat pa se on prosledi obema nitima a njegove metode su syncrhonized. Napravi jednu klasu za upisivanje, pa jedan isti objekat prosledi svakoj niti a njegova metoda za upisivanje neka bude sinhronizovana. Znaci ne kao sto ovde hoces, nego samo jedan objekat!
 
Odgovor na temu

hyle
Perica Milošević
Belgrade

Član broj: 30030
Poruke: 150
*.static.ikomline.net.

Sajt: www.linkedin.com/in/peric..


+4 Profil

icon Re: Dodavanje zapisa u fajl kroz vise thread-ova20.05.2008. u 19:40 - pre 193 meseci
Citat:
googol:
Mada, kada sada razmislim - trebao sam mozda izvesti da svi threadovi pristupaju istoj instanci klase UpisPodatakaUFajl

Tako je, ključna reč synchronized se uvek odnosi na podatke, a ne na metode, bez obzira što je nekada navodiš u deklaraciji metode. U tvoj slučaju, thread koji izvršava metodu upisiPodatke zahteva eksluzivan pristup objektu klase UpisPodatakaUFajl nad kojim poziva metodu. Ti si svakom od threadova dao poseban objekat i time nisi obezbedio željeno zaključavanje.

Ovo:
Code:

  public synchronized void upisiPodatke(Kvadrat kvadrat) {
    // telo metode
  }

je isto što i ovo:
Code:

  public void upisiPodatke(Kvadrat kvadrat) {
    synchronized (this) {
      // telo metode
    }
  }


Paralelno pisanje iz više threadova u isti fajl, implementirano na ovaj način (sa ispravno urađenim zaključavanjem), nema mnogo smisla jer dobijaš komplikovan kod koji radi jednakom brzinom kao da si imao samo jedan thread. Ukoliko želiš asinhrone IO operacije onda predlažem da koristiš NIO implementaciju za rad sa fajlovima, npr. klasu FileChannel.
 
Odgovor na temu

googol

Član broj: 181890
Poruke: 6
85.94.121.*



Profil

icon Re: Dodavanje zapisa u fajl kroz vise thread-ova22.05.2008. u 18:01 - pre 193 meseci
hvala na odgovorima.

Citat:

Paralelno pisanje iz više threadova u isti fajl, implementirano na ovaj način (sa ispravno urađenim zaključavanjem), nema mnogo smisla jer dobijaš komplikovan kod koji radi jednakom brzinom kao da si imao samo jedan thread


Ne, brzina upisivanja mi uopste nije vazna. Ovi threadovi koje imam rade nesto, i samo mi je vazno da na kraju upisu u jedan isti fajl da su zavrsili. Pa hoce li to uciniti koju milisekundu prije ili kasnije ili hoce li u TOM dijelu ( nakon sto su zavrsili vaznu proceduru ) cekati jedan drugoga, to mi ne igra nikakvu ulogu.

Ja sam problem ( nadam se? ) rijesio tako sto sam stavio da je metoda upisiPodatke staticka, te kad umjesto
new UpisPodatakaUFajl().upisiPodatke(kvadrat); stavim UpisPodatakaUFajl.upisiPodatke(kvadrat) onda sve ( za sada? ) savrseno radi...

Moze li ovo biti konacno (i pravilno) rijesenje mog problema?

 
Odgovor na temu

[es] :: Java :: Dodavanje zapisa u fajl kroz vise thread-ova

[ Pregleda: 2857 | Odgovora: 5 ] > FB > Twit

Postavi temu Odgovori

Navigacija
Lista poslednjih: 16, 32, 64, 128 poruka.