Synchronizacja wątków jak działa.

0

Uczę się o wątkach.Muszę zrobić program z sychronizacją.Nie jestem pewien jak dokładnie działa ten kod a chcę go wykorzystać czy ktoś może mi wyjaśnić lub podać adresy z tutoriami do wątków.

public class nowy 
{
  boolean start = true;
//	
  public synchronized void zajety()
  {
	 zajety = false;
  }
  
  public void wolny()
  {
	 zajety = true;	
  }
}
0

Ten kod nie działa. No chyba ze metoda wolny() tez będzie synchronizowana.
Synchronizacja w ten sposób sprawia że w danej chwili tylko jedna metoda dla danego obiektu moze byc wykonywana. Tzn jeśli jeden wątek wykonuje zajęty() to drugi wątek musi czekać żeby móc użyć synchronizowanej metody tej klasy.

0

Tutoriale jak zwykle na stronach Oracle http://docs.oracle.com/javase/tutorial/essential/concurrency/

0

Klasa nowy dotyczy tej części kodu.Jeśli dobrze zrozumiałem pierwszy-nowy.zajety(); się wykonuje następnie jest blokowany i zaczyna działać drugi-nowy.wolny(); czy tak czy źle zrozumiałem.

**public void tankuj() throws InterruptedException**
{
**  if(paliwo1 <=20 && nowy.parking==true)**////jeśli paliwo1 jest mniejsza bądz równa 20 i nowy.parking jest równy  bedzie prawda
     
    {
		nowy.zajety();
		System.out.println("samochód (numer:" + nr +") (paliwo:" + paliwo1 + ") wjechał");
		Thread.sleep(1000);
		System.out.println("samochód  (numer:" + nr +") (paliwo:" + paliwo1 + ")  zaparkował/zatankował");
		Thread.sleep(5000);
		paliwo1 = (rnd.nextInt(10)+1)*50;
		System.out.println("samochód  (numer:" + nr +")  (paliwo:" + paliwo1 + ")  zatankowany/wyjechał");
		Thread.sleep(1000);
		nowy.wolny();
	}	
}
0

Nic nie zrozumiałeś. To jest zabezpieczenie przed jednoczesnym tankowaniem dwóch samochodów. Wjeżdża jeden samochód i blokuje miejsce, a potem na koniec je odblokowuje. Przy czym jest to zrobione źle, bo tak na prawdę synchronizacja powinna być zrobiona na podstawie referencji do obiektu "nowy" a nie tylko w jego metodach. Czemu? Bo nadal może się zdarzyć tak:

  • wątek 1 sprawdza warunek ifa i wchodzi do bloku
  • wątek 2 sprawdza warunek ifa i wchodzi do bloku (zmienna nowy.parking nadal jest ustawiona na true!)
    no i niestety nasza synchronizacja guzik dała, bo oba wątki weszły do sekcji krytycznej i wartość zmiennej paliwo1 jest uzależniona od race condition.
0

Powinieneś mieć klasę Parking (Dystrybutor), która ma synchronizowaną metodę tankujSamochod(Samochod samochod). Wtedy dany Parking (Dystrybutor) będzie mógł tankowac tylko jeden samochód naraz.

0

Coś takiego.

public class Stacjasamochodowa {

	boolean czyJestWolnyDystrybutor;

	int iloscDystrybutorow;
	int aktualnaIloscDystrybutorow;

	public boolean czyJestWolnyDystrybutor(){
		return czyJestWolnyDystrybutor;

	}

	public synchronized void zajmijDystrybutor(){

		if(aktualnaIloscDystrybutorow < iloscDystrybutorow)
			czyJestWolnyDystrybutor = false;
		else{
			czyJestWolnyDystrybutor = true;
		}
	}

	public void zwolnijDystrybutor(){
		czyJestWolnyDystrybutor = true;

	}

	public Stacjabenzynowa(int iloscMiejsc_){
		iloscDystrybutorow = iloscMiejsc_;
		System.out.println("Stacjabenzynowa");
		System.out.println("Ilosc wolnych dystrybutorow:" + iloscDystrybutorow);

		czyJestWolnyDystrybutor = true;

	}


}
0

Też nie do końca ponieważ można odczytać, że dystrybutor jest wolny, ale w tym czasie inny wątek może zająć dystrybutor wywołując metodę zajmijDystrybutor. Jeżeli już chcesz coś synchronizować to zamiast metod używaj bloków synchronize z muteksem na czyJestWolnyDystrybutor.

0

Absolutnie nie rób synchronizacji po obiekcie "czyJestWolnyDystrybutor"! W instancji JVM istnieją tylko dwa obiekty typu Boolean - true i false. W efekcie synchronizacja po Booleanie może się skończyc deadlockiem jak się okaże że w dwóch miejscach ktoś tak zrobił...

0

Do tego konkretnego zadania najlepiej nadaje się Semaphore.
http://docs.oracle.com/javase/6/docs/api/java/util/concurrent/Semaphore.html

  1. Tworzysz jeden semafor
    Semaphore sem = new Semaphore(iloscDystrybutorow);

  2. Tankowanie:
    sem.acquire();
    try {
    //tutaj tankowanie
    } finally {
    sem.release();
    }

0

Witam zrobiłem cos takiego tylko ,że nie pokazuje mi Okna JFrame nie wiem dlaczego.

import java.awt.Color;


autor ek
import java.awt.Dimension;
import javax.swing.*;


import javax.swing.ImageIcon;
import javax.swing.JFrame;

import javax.swing.JButton;
import java.util.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;

 
public class Samochód extends JFrame
{
  
int paliwo1;
int nr;
int paliwo2;
Parking parking;
private static Parking parking; 
Random rnd = new Random();

JTextArea textArea = new JTextArea();
JScrollPane panelprzewijania=new JScrollPane(textArea); 
JButton start ;
JButton koniec;
 
public Samochód(int Nr, int Paliwo1, int Paliwo2, Parking parking  )
   {
setLayout(null);//menedżer rozkładu (layout)Zmiana menedżera rozkładu – metoda setLayout
setPreferredSize(new Dimension(640,445));
setBackground(new Color(210,246,255));

start=new JButton("Start", new ImageIcon("images/analiza.png")); 
koniec=new JButton("Start", new ImageIcon("images/analiza.png")); 
panelprzewijania=new JScrollPane(textArea,JScrollPane.VERTICAL_SCROLLBAR_ALWAYS,JScrollPane.HORIZONTAL_SCROLLBAR_AS_NEEDED);
add(koniec);
add(start);
start.setBounds(20,125,105,30); 
add(textArea);
textArea.setBounds(20,165,270,200); 
add(panelprzewijania);
panelprzewijania.setBounds(20,165,270,200); 

//------------------------------------------------------------------------------

nr = Nr;
paliwo1 = Paliwo1;
paliwo2 = Paliwo2;  
parking =  Parking;
textArea.append("Samochod[Numer:" + nr +"] [Paliwo:" + paliwo1+".\n");
	
}
 
  public void jazda() throws InterruptedException
{   
	Thread.sleep(1000);
	paliwo1 = paliwo1 - 10;
		if(paliwo1 > paliwo2)
		{	textArea.append("Samochód [Numer:" + nr +"] [Paliwo:" + paliwo1+ "jedzie na misję.\n");
			//System.out.println("Samochód [Numer:" + nr +"] [Paliwo:" + paliwo1 + "] jedzie na misję");
			Thread.sleep(1000);
		}
		else  
		if(paliwo1 <= 20 && parking.nowy == false )
	    {  	textArea.append("Samochód [Numer:" + nr +"] [Paliwo:" + paliwo1+"wykonano misję/zatrzymał sie.\n");
	        //System.out.println("Samochód [Numer:" + nr +"] [Paliwo:" + paliwo1 + "] wykonano misję/zatrzymal sie");
			Thread.sleep(1000);
	    //}	      
	    //else  
		//if(paliwo1 <= 20 && parking.nowy == false )
		//{
		   // System.out.println("Samolot [Numer:" + nr +"] [Paliwo:" + paliwo1 + "] zatrzymal sie");
			//Thread.sleep(1000);
		}    
		else  
        if(paliwo1 < paliwo2)
        {       textArea.append("Samochód [Numer:" + nr +"] [Paliwo:" + paliwo1+"wraca z podruzy.\n");
        	//System.out.println("Samochód [Numer:" + nr +"] [Paliwo:" + paliwo1 + "] wraca z podruzy");
			Thread.sleep(1000);
        }
}
		     
  public void tankowanie() throws InterruptedException
{
  if(paliwo1 <=20 && parking.nowy==true)
    {
		parking.Zajety();
		//System.out.println("Samochod [Numer:" + nr +"] [Paliwo:" + paliwo1 + "] podjezdza do stacji");
		//Thread.sleep(1000);
                textArea.append("Samochod[Numer:" + nr +"] [Paliwo:" + paliwo1+"zatrzymal sie/tankuje.\n");
               
		//System.out.println("Samochod [Numer:" + nr +"] [Paliwo:" + paliwo1 + "] zatrzymal sie/tankuje");
		Thread.sleep(5000);
		paliwo1 = (rnd.nextInt(10)+1)*100;
                textArea.append("Samochod [Numer:" + nr +"] [Paliwo:" + paliwo1+"zatankował/jedzie.\n");
               
		//System.out.println("Samochód[Numer:" + nr +"] [Paliwo:" + paliwo1 + "] zatankował/jedzie");
		Thread.sleep(1000);
		parking.Wolny();
	}	
}   
        public void run()
{
 try
   {
	do
	  {
	   tankowanie();
	   jazda();					
	  }
        
	 while(paliwo1>0);
        textArea.append("Samochód [Numer:" + nr +"] [Paliwo:" + paliwo1+"zatrzymal sie .\n");
	 //System.out.println(" Samochód [Numer:" + nr +"] [Paliwo:" + paliwo1 + "] zatrzymał sie  ");
	}
  catch (InterruptedException e)
  {
  return;
  }

 start.addActionListener(new ActionListener (){
 public void actionPerformed (ActionEvent e){

 for(int i=1; i<=3; i++)
      {
	      Random rnd = new Random();
	      int paliwo1 = (rnd.nextInt(10)+1)*100;
	      int paliwo2 = paliwo1/2 + 20;
	      new Samolot(i, paliwo1, paliwo2, Parking).start();	
	      }
    }
    } );
    koniec.addActionListener(new ActionListener () {
    	public void actionPerformed(ActionEvent e){
    	   System.exit(0);
    	}
    });
    
   setVisible(true);
   setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
}

	public static void main(String[] args) {
		 
		  parking = new Parking(); // stworzenie obiektu

	}

    private void start() {
        throw new UnsupportedOperationException("Not yet implemented");
    }
}
public class Parking

{
  boolean nowy = true;
	
  public synchronized void Zajety()
  {
	nowy = false;
  }
   
  public void Wolny()
  {
	nowy = true;	
  }
}

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