Działanie wątku

0

Witam, krótko przedstawię mój problem. Mam okienko z jakimiś widgetami oraz klasę która dziedziczy po Thread. W wątku mam mniej więcej taki kod:

public void run() {
      while (true) {
            if (jakas_zmienna) {
                  // robi cos tam
            } else {
                  // robi co innego
            }
      }
}

A jeden z przycisków zmienia wartość tej zmiennej (przyjmijmy że jest to bool).
Problem jest w tym, że wątek nie zawsze reaguję na zmianę tej zmiennej. A powiedziałbym nawet, że w ogóle nie reaguje. Nie miałem zbyt dużo doczynienia z wątkami w javie. Czy jest to problem z synchronizacją? Trzeba sie bawić w jakieś semafory/mutexy etc? A jeżeli nie to jak to rozwiązać? Dziękuję za pomoc i pozdrawiam.

0

Jeśli przycisk ma zmieniać wartość zmiennej w wątku, to należałoby po prostu w metodzie actionPerformed zmieniać tą wartość, jeśli nastąpi kliknięcie przycisku.

W wątku muszą być obecne metody ustawiające i pobierające wartość zmiennej.

Poniżej jest schemat takiego programu

public class Test extends JFrame implements ActionListener
{
	private JButton przycisk = new JButton("przycisk");
	JPanel panel = new JPanel();
	Watek w = new Watek(); //obiekt wątku
	
	
	public Test()
	{
		setSize(250,400);
		setDefaultCloseOperation(EXIT_ON_CLOSE);
		przycisk.addActionListener(this);
		panel.add(przycisk);
		w.start();
		add(panel);
	}
	
	public void actionPerformed(ActionEvent e)
	{
		Object ob = e.getSource();
		if (ob == przycisk)
		{
			boolean wartosc = w.getA(); //pobieramy wartosc zmiennej
			if(wartosc == true) //sprawdzamy wartosc
			{
				w.setA(false); //ustawiamy
			}
			else w.setA(true);
		}
	}
			
	
	public static void main(String[] args)
	{
		Test test = new Test();
		test.setVisible(true);
	}
}

class Watek extends Thread
{
	boolean a = true;
	public Watek()
	{
		this.a = true;
	}
	
	public void run()
	{
		while(true)
		{
			try {
			
			if(a == true)
			{
				System.out.println("jest prawdziwy");
				
			}
			sleep(2000);
			}
			catch (InterruptedException e)
			{
			}
		}
	}
	
	public void setA(boolean a)
	{
		this.a = a;
	}
	
	public boolean getA()
	{
		return a;
	}
}
0

No tak, powinno tak być. U mnie jest tak:
Patrząc na tamten napisany przez mnie pseudokod najpierw wątek wskakuje do pierwszej części ifa (bo zmienna bool ma wartość true), potem jak wciskam przycisk to wartość zmiennej zmienia się, ale wątek na nią nie reaguje i tak jakby stoi. A powinien przy następnym obiegu while(true) wejść do drugiej części ifa.

Rozumiem to co napisałeś, ale nie tu mam problem.

EDIT:
Wstawiłem sobie println'a na początku petli nieskonczonej i wygląda to tak jakby wątek w ogóle się zatrzymywał w momencie zmiany wartości tej zmiennej.

EDIT:
Ok, sorki, trochę spanikowałem, zapętlał mi się wewnętrz run'a...

0

może po prostu wątek nie wychodzi z if-a bo coś tam robi lub na coś czeka i dlatego wygląda tak jakby się zatrzymał.
Lub też może wątek ginie - z run'a nie lecą jakieś wyjątki?

0

Zrob ta zmienna ktora czyta watek a zmienia guzik jako volatile.

0
::. napisał(a)

Zrob ta zmienna ktora czyta watek a zmienia guzik jako volatile.

W przeciwnym przypadku optymalizator kodu, nie wiedząc, że zmieniasz zmienną w innym wątku, może Ci kod zoptymalizować w ten sposób, jakby zmienna nigdy nie zmieniała swojej wartości, czyli pominąć w ogóle if-a. Optymalizator kodu nie analizuje kodu innych wątków - jest to zbyt skomplikowane i za bardzo czasochłonne, dlatego trzeba mu podpowiedzieć, żeby nie ruszał tej zmiennej (nie optymalizował kodu wokół niej) poprzez słówko kluczowe jak powyżej.

1 użytkowników online, w tym zalogowanych: 0, gości: 1