Witam...
Mam taki pytanie:
Czy metoda run(), może modyfikować wartości składowych obiektu Thread na rzecz kórego została wykonana??
Witam...
Mam taki pytanie:
Czy metoda run(), może modyfikować wartości składowych obiektu Thread na rzecz kórego została wykonana??
Jeżeli nie są one final lub w ogólności nie dostępne to tak.
Niestety właśnie nie bardzo mi to działa. Może zamieszcze kod:
public class DFSThread extends Thread {
private Node root;
private String name;
public int[] val;
public void run() {
Tree tD = new Tree();
this.val = tD.DFS(root);
}
public DFSThread(Node n) {
this.root = n;
this.name = "DFS";
this.val = new int[2];
}
public int[] getVal() {
return this.val;
}
public String getAlgorithmName() {
return this.name;
}
}
metoda run() modyfikuje wartość składowej val (już nawet zrobiłem ja pupliczną - łamiąc zasadę hermetyzacji), następnie metoda getVal() pobiera tą wartość, niestety na zewnątrz klasy ma ona wartość 0, a z pewnością tak nie jest bo wcześniej wypisuje ją na konsoli.
jeszcze wywołanie:
dfs.start();
.
.
.
fileLine = fileLine + dfs.getAlgorithmName() + '-' + Integer.toString(dfs.getVal()[0]) + '-' + Integer.toString(dfs.getVal()[1]) + '/';
prosze o pomoc... :-|
W twoim programie masz dwa wątki-główny i ten który stworzyłeś. Po wywołaniu start() działają one jednocześnie.
Prawdopodobnie wątek główny dochodzi do dfs.getVal() zanim ten drugi wykona this.val = tD.DFS(root);
Wątek główny musi poczekać, aż tamten drugi się skończy.
Proponuję użyć klasy java.util.concurrent.CountDownLatch
CountDownLatch latch = new CountDownLatch(1); /* bariera zainicjalizowany na 1 */
DFSThread dfs = new DFSThread(node, latch); /* musimy przekazać bariere */
dfs.start();
latch.await();
.
.
.
fileLine = fileLine + dfs.getAlgorithmName() + '-' + Integer.toString(dfs.getVal()[0]) + '-' + Integer.toString(dfs.getVal()[1]) + '/';
public class DFSThread extends Thread {
private Node root;
private String name;
private CountDownLatch latch;
public int[] val;
public void run() {
Tree tD = new Tree();
this.val = tD.DFS(root);
latch.countDown(); /* zwalniamy wątek główny */
}
public DFSThread(Node n, CountDownLatch latch) {
this.root = n;
this.name = "DFS";
this.latch = latch;
this.val = new int[2];
}
public int[] getVal() {
return this.val;
}
public String getAlgorithmName() {
return this.name;
}
}
Wprawdzie nie wiem jak działa u ciebie Tree::DFS, ale to jest dosyć podejrzane:
Tree tD = new Tree();
this.val = tD.DFS(root);
Przecież tworzysz nowe drzewo. Czy na pewno o to ci chodzi?
No chyba, że procedura nie używa td, a jedynie root.
W takim jednak przypadku lepiej zrobić metodę statyczną:
public class Tree{
(...)
public static int[] DFS(Tree root){
(...)
}
}
A później wywołać to tak: this.val = Tree.DFS(root)
działa - wielkie dzięki, ale mam wątpliwości, co do szybkości obliczeń. Mianowicie program analizuej drzewo na 4 sposoby. oczywiście przeszukiwanie BFS jest w większości przypadków najwolniejsze, kiedy nie korzystałem z obiektu CountDownLatch przeszukiwania kończyły się zazwyczaj w kolejności najszybsz-...-najwolnijeszy (wyniki były wypisywane na konsoli po zakończeniu) teraz wypisują się w kolejności wywołania (zaczynając od najwolniejszebo BFSa). Jak to sią ma do siebie? Czy po prostu wszystkie pozostałe metody są już policzone i czekają na zakończenie BFSa i wszystko jest wtedy wypisywane?? [???]
@costa, nigdy przenigdy nie mierz wydajności za pomocą czasu wykonania. Szczególnie w Javie, bo nie masz kontroli nad GC i nawet najszybsza metoda może zostać przerwana na długi czas przez wywołanie GC. Może się tez tak zdarzyć, że wątek najszybszej metody będzie opóźniany przez JVM w tylko jej znanym celu.
Prawidłową metodą jest wybranie pewnej bazowej operacji, która wykonywana jest we wszystkich metodach np. porównanie przez wywołanie komparatora w sortowaniu lub ilość zaliczonych węzłów w metodach wyszukiwania w drzewach. Wtedy licząc ilość takich wywołań możesz powiedzieć co jest szybsze, a co wolniejsze. Czas jest bardzo kiepskim miernikiem.
Oczywiście @Koziołek zgadzam sie z Tobą w 100%. Porównuje liczbę rzesziukanych węzłów i ścieżke rozwiązania, ale chodzi mi o czas jaki muszę oczekiwać na te wyniki
Mówiąc filozoficznie, testy zawsze trwają wieki. Niezależnie jak będziesz próbował równolegle wywoływać metody testujące to ilość czasu pozostanie z grubsza taka sama. Tu nie przeskoczysz niczego niestety.
W każdym razie wielkie dzięki za pomoc. teraz pozostanie mi tylko stworzyć wykres i tutaj tez takie małe pytanko: jest do tego jakiś komponent (bo nie słyszałem), czy też trzeba sobie radzić samemu?? Wiem, ze pytanie trochę off-topic, jednak proszę tylko o krótką odpowiedź, ewentualnie nazwę komponentu i poszukam sobie już sam...
Jeszcze raz dzięki za pomoc
JFreeChart - to taka fajna biblioteka jest
Nie wiem, czy dobrze zrozumiałem, ale jeśli z jakichś powodów chcesz odpalić te cztery przeszukiwania jednocześnie na czterech różnych wątkach, a wątek główny ma czekać na zakończenie tamtych wątków, to CountDownLatch zainicjalizuj na 4, a latch.countDown() użyj dokładnie raz w każdym wątku na koniec.
Jeżeli jeszcze się nie domyśliłeś, to wąŧek wiszący na barierze jest zwalniany, gdy jej wartość dojdzie do 0, a countDown() zmniejsza ją o 1.