2011-08-22 17 views
6

Potrzebuję zdefiniować wspólną zmienną w metodzie main() klasy głównej. Potrzebuję dwóch wątków, aby móc uzyskać dostęp do tej wspólnej zmiennej. Tworzę wątki poprzez implementację interfejsu Runnable i implementację metody abstract run() interfejsu. Jak odnieść się do wspólnej zmiennej zdefiniowanej w metodzie main() klasy Main z metody run() zdefiniowanej w mojej klasie, która implementuje interfejs Runnable? Oczywiście zwyczajne wywoływanie ich po imieniu nie działa - ponieważ pojawiają się one w moim zasięgu Runnable.uzyskiwanie dostępu do zmiennej współdzielonej z klasy Runnable

EDIT - Przepraszam, jest tu prosty przykład

public Class DoThread implements Runnable { 

    public void run(){ 
     sharedVar += 1 
    } 


} 

w osobnym pliku .class:

public Class Main { 

    public static void main(String[] args) { 
     int sharedVar = 0; 

     Thread t1 = new Thread(new DoThread()); 
     Thread t2 = new Thread(new DoThread()); 

     t1.start(); 
     t2.start(); 

     t1.join(); 
     t2.join(); 

    } 


} 

więc powinienem być tworzenia obiektu do przechowywania udostępnionego var i następnie przekazywanie tego obiektu do konstruktorów DoThread() podczas tworzenia wątków? Czasem zdarza mi się pomieszać między kiedy java przechodzi przez ref lub przechodzi przez var, więc jeśli zrobię to w ten sposób, zmieni się do wspólnego var przez t1 być postrzegane przez t2?

+0

Czy możesz opublikować swój kod? – SJuan76

+0

Zawsze staraj się opublikować [SSCCE] (http://sscce.org/). –

Odpowiedz

10

Cóż, jeśli zadeklarujesz zmienną lokalną , nie będziesz w stanie odnosić się do niej nigdzie indziej niż w klasach utworzonych w ramach tej metody.

Gdzie wdrażasz Runnable? Jeśli jest to ta sama klasa, możesz albo uczynić ją zmienną instancji, albo ustawić zmienną na tej samej instancji, z której tworzysz wątek, albo ustawić ją jako zmienną statyczną. Jeśli Runnable jest zaimplementowany w innej klasie, to kiedy skonstruujesz instancję tej klasy, możesz podać jej potrzebne dane - nie jest jasne, co to dokładnie oznacza w tym momencie ... Jak powiedzieli inni, kod byłby użyteczny. (Na przykład, czy gwinty muszą być w stanie zobaczyć zmienia w oryginalnych danych?)

Tak na marginesie, gwintowania jest stosunkowo zaawansowany, podczas propagacji danych między klasami jest stosunkowo proste. Jeśli jesteś nowicjuszem w Javie, polecam rozpoczęcie pracy na łatwiejszych rzeczach niż wątki.

EDIT: Dla przykładu, należy użyć AtomicInteger coś takiego:

import java.util.concurrent.atomic.AtomicInteger; 

class DoThread implements Runnable { 

    private final AtomicInteger counter; 

    DoThread(AtomicInteger counter) { 
     this.counter = counter; 
    } 

    public void run() { 
     counter.incrementAndGet(); 
    } 
} 

public class Test { 
    public static void main(String[] args) throws InterruptedException { 
     AtomicInteger shared = new AtomicInteger(0); 

     Thread t1 = new Thread(new DoThread(shared)); 
     Thread t2 = new Thread(new DoThread(shared)); 

     t1.start(); 
     t2.start(); 

     t1.join(); 
     t2.join(); 

     System.out.println(shared.get()); // Prints 2 
    } 
} 
+0

dzięki jon - dodałem przykład w oryginalnym poście^ –

+0

@Dave: Podałem przykład, w jaki sposób można zmienić kod. Nadal uważam, że jeśli dzielenie się danymi między różnymi obiektami jest dla ciebie względnie nowe, prawdopodobnie nie jesteś gotowy na dodatkowe problemy z wątkami. –

7

Kod byłby przydatny.

Jeśli używasz klasy anonimowej, możesz zadeklarować zmienne jako final i będą one dostępne w anonimowej klasie.

public void main(String[] args) { 
    final int myvar = 0; 
    new Thread(new Runnable() { 
     public void run() { 
      System.out.println("myvar: "+myvar); 
     } 
    }).start(); 
} 
2

Musisz podać odniesienie do wartości wspólnej. Jeśli nie jest to już odnośnik, musisz go zmienić na AtomicReference, AtomicInt itp. Lub tablicę wartości, którą chcesz udostępnić.

0

To jest miejsce, gdzie PassByRef jest bardziej skuteczne. Przekaż swoje zmienne odwołanie do obu uruchamianych instancji. To wszystko ... od tego czasu można się odwoływać do metody uruchamiania.

Ex: Th1

Temat = new Thread (Myrunnable (varRef)). Podobnie w przypadku innych wątków:

+0

jest to, co wspomniałem w mojej edycji tego rodzaju? –

Powiązane problemy