• Najnowsze pytania
  • Bez odpowiedzi
  • Zadaj pytanie
  • Kategorie
  • Tagi
  • Zdobyte punkty
  • Ekipa ninja
  • IRC
  • FAQ
  • Regulamin
  • Książki warte uwagi

question-closed Problem watki

Object Storage Arubacloud
0 głosów
202 wizyt
pytanie zadane 28 listopada 2015 w Java przez plox Początkujący (320 p.)
zamknięte 20 marca 2016 przez plox

Witam otóż musze napisać program który korzysta z wątków tak aby przyspieszyc dzialanie programu, wlasciwego programu nie bede zamieszczal ale stworzylem cos bazujacego na tym programie i uzylem watkow. Problem jest w tym ze nie wiem czy zrobilem to dobrze(wedlug mnie nie ma zadnej roznicy), a jak nie to jak to sie robi bo moze zle rozumuje w tym temacie. Z gory dziekuje za pomoc.

 

// NewClass


package test2;

import java.io.BufferedReader;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.IOException;
import java.io.PrintWriter;
import java.util.LinkedList;
import java.util.logging.Level;
import java.util.logging.Logger;

public class NewClass implements Runnable
{
    private final int i;

    NewClass(int i) {
        this.i = i;
    }
    @Override
    public void run()
    {
    LinkedList <String> lista1 = new LinkedList<String>();
        
        File file = new File("pliczek.txt");
        int dlugosc = 500000;
        //tworzenie
        for(int i = 0 ; i<dlugosc ; i++)
        {
            int x = i+2;
            i++;
            String a = Integer.toString(x);
            lista1.add(a);
        }
        //zapisywanie
        
        try {
        try (PrintWriter pr = new PrintWriter(file)) {
            for(String n : lista1)
            {
                pr.println(n);
            }
        }
            lista1.clear();
        } catch (FileNotFoundException ex) {
            Logger.getLogger(Test2.class.getName()).log(Level.SEVERE, null, ex);
        }
        
        
        
    
    }
}



 

// NewClass2


package test2;

import java.io.BufferedReader;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.IOException;
import java.util.LinkedList;
import java.util.logging.Level;
import java.util.logging.Logger;


public class NewClass2 implements Runnable
{
    private final int i;

    NewClass2(int i) {
        this.i = i;
    }
    public void run()
    {
        
        
        try {
            Thread.sleep(150);
                  File file = new File("pliczek.txt");
        // odczytywanie
        LinkedList <String> lista2 = new LinkedList<String>();
        try {
            FileReader fr = new FileReader(file);
            BufferedReader br = new BufferedReader(fr);
            String line = "";
            while(line != null)
            {
                try {
                    line = br.readLine();
                } catch (IOException ex) {
                    Logger.getLogger(Test2.class.getName()).log(Level.SEVERE, null, ex);
                }
                lista2.add(line);
            }
            } catch (FileNotFoundException ex) {
                Logger.getLogger(Test2.class.getName()).log(Level.SEVERE, null, ex);
            }
        
        //wypisanie odczytanych
        lista2.removeLast();
        for(String m : lista2)
        {
            System.out.println(m);
        }
        lista2.clear();
        } catch (InterruptedException ex) {
            Logger.getLogger(NewClass2.class.getName()).log(Level.SEVERE, null, ex);
        }
        
    }
}


 

// Test2


package test2;

import java.io.BufferedReader;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.IOException;
import java.io.PrintWriter;
import java.util.LinkedList;
import java.util.logging.Level;
import java.util.logging.Logger;


public class Test2  
{
    
    public static void main(String[] args) throws FileNotFoundException, IOException 
    {
       Runnable[] runners = new Runnable[1];
        Thread[] threads = new Thread[1];
 
        for(int i=0; i<1; i++) {
            runners[i] = new NewClass(i);
        }
 
        for(int i=0; i<1; i++) {
            threads[i] = new Thread(runners[i]);
        }
 
        for(int i=0; i<1; i++) {
            threads[i].start();
        }
        
        Runnable[] runners2 = new Runnable[1];
        Thread[] threads2 = new Thread[1];
        
        for(int i=0; i<1; i++) {
            runners2[i] = new NewClass2(i);
        }
 
        for(int i=0; i<1; i++) {
            threads2[i] = new Thread(runners2[i]);
        }
 
        for(int i=0; i<1; i++) {
            threads2[i].start();
        }
        
        
        
    }
    
}

 

komentarz zamknięcia: rozwiązane

1 odpowiedź

0 głosów
odpowiedź 29 listopada 2015 przez tymon_rogowski Bywalec (2,960 p.)
wybrane 4 grudnia 2015 przez plox
 
Najlepsza

W twoim przykładzie kod z pierwszego wątku wykonuje się u mnie około 70 milisekund, możesz to zmierzyć obejmując swój kod w:

long start = System.currentTimeMillis();
...
long end = System.currentTimeMillis();
System.out.println("NewClass: " + (end - start));

Drugi wątek w tym samym czasie czeka 150 milisekund po czym zaczyna wczytywać dane z pliku które zostały zapisane w pierwszym.

Wnioski z tego są następujące:

a) Zamiast uzyskać przyspieszenie w moim przypadku tak naprawdę całość działa wolniej bo program przez około 80ms tak naprawdę nic nie robi.

b) Program działa na dwóch wątkach (poza main) ale kod w nich i tak wykona się sekwencyjnie.

b) Stosowanie mechanizmów w stylu Thread.sleep(150) jest w tym przypadku niebezpieczne bo na szybkich maszynach powoduje straty w czasie a na zbyt wolnych drugi wątek może zacząć czytac plik zanim pierwszy skończy zapisywać. Normalnie jest to coś czego byśmy chcieli ale poprawne obsłużenie tego przypadku jest trochę bardziej skomplikowane, zobacz na http://stackoverflow.com/questions/17637176/access-file-through-multiple-threads może to jest to czego potrzebujesz.

 

Nie wiem jaki jest Twój oryginalny przypadek ale zapis i odczyt do pliku stanowi tutaj bottleneck bo został umieszczony "pomiędzy" jednym a drugim wątkiem. Jeśli nie jest krytyczne aby zapis do pliku odbywał się właśnie w tym momencie to może warto trochę inaczej podejść do problemu. Dane i tak masz w pamięci wiec można je przekazywać z jednego wątku do drugiego np. przez kolejkę - https://docs.oracle.com/javase/7/docs/api/java/util/concurrent/ConcurrentLinkedQueue.html. 

Dla przykładu jeśli masz klasę A która generuje liczby i wygenerowanie jednej zajmuje 100 milisekund oraz klasę B która konsumuje te liczby i operacja na jednej liczbie zajmuje 200 milisekund to tworzysz np. jeden wątek dla klasy A i dwa wątki dla klasy B żeby się wszystko z balansowało. Dodatkowo jeśli dalej chcesz zapisywać do pliku to tworzysz klasę C dla której będziesz miał jeden wątek - on będzie tylko odbierał dane z klasy A przez osobną kolejkę i zapisywał do pliku nie przeszkadzając wątkom z klasy B.

komentarz 2 grudnia 2015 przez plox Początkujący (320 p.)
Dziekuje za odpowiedź, spróbuje pojść tą koncepcją zobaczymy co z tego wyniknie i poczytam jeszcze troche oraz zrobie to metodą prób i błedów. Pierwszy raz stykam się z wątkami w mojej przygodzie z programowaniem(zawsze operowałem tylko na głownym wątku). także napewno mi to pomoże bardziej zrozumieć te kwestie.

Podobne pytania

0 głosów
2 odpowiedzi 523 wizyt
pytanie zadane 24 października 2015 w C i C++ przez Horace17 Obywatel (1,070 p.)
0 głosów
1 odpowiedź 721 wizyt
+1 głos
3 odpowiedzi 432 wizyt
pytanie zadane 10 lipca 2019 w Java przez anonymousProgrammer Początkujący (350 p.)

92,575 zapytań

141,424 odpowiedzi

319,649 komentarzy

61,960 pasjonatów

Motyw:

Akcja Pajacyk

Pajacyk od wielu lat dożywia dzieci. Pomóż klikając w zielony brzuszek na stronie. Dziękujemy! ♡

Oto polecana książka warta uwagi.
Pełną listę książek znajdziesz tutaj.

Akademia Sekuraka

Kolejna edycja największej imprezy hakerskiej w Polsce, czyli Mega Sekurak Hacking Party odbędzie się już 20 maja 2024r. Z tej okazji mamy dla Was kod: pasjamshp - jeżeli wpiszecie go w koszyku, to wówczas otrzymacie 40% zniżki na bilet w wersji standard!

Więcej informacji na temat imprezy znajdziecie tutaj. Dziękujemy ekipie Sekuraka za taką fajną zniżkę dla wszystkich Pasjonatów!

Akademia Sekuraka

Niedawno wystartował dodruk tej świetnej, rozchwytywanej książki (około 940 stron). Mamy dla Was kod: pasja (wpiszcie go w koszyku), dzięki któremu otrzymujemy 10% zniżki - dziękujemy zaprzyjaźnionej ekipie Sekuraka za taki bonus dla Pasjonatów! Książka to pierwszy tom z serii o ITsec, który łagodnie wprowadzi w świat bezpieczeństwa IT każdą osobę - warto, polecamy!

...