andbin ha scritto:
Per mettere in sospensione il thread corrente si usa Thread.sleep(millisecondi)
ho usato il TimeUnit.SECONDS.sleep(ext);
comunque, grossomodo l'esercitazione l'ho finita. ma sono tremendamente insicuro su 2 cose:
la classe message, che dovrebbe gestire i flussi, e il fatto che creo l'oggetto message sia nella miniera, per mandare un wait in caso ci sono 3 minatori tutti occupati, passandogli il socket, e poi creo un secondo oggetto message su miner a cui passo il socket passato al costruttore del miner. non vorrei fosse sbagliato. voglio dire, se creo l'oggetto message dentro alla miniera, e leggo i flussi, e poi lo creo dentro al minatore, e rileggo i flussi dallo stesso socket cui già li ho letti prima, in teoria dovrebbe funzionare giusto?
incollo il codice completo, e se possibile, vorrei un'opinione, magari anche dirmi se questi miei 2 dubbi sono fondati.
miniera
package Miniera;
import java.io.IOException;
import java.io.PrintStream;
import java.net.ServerSocket;
import java.net.Socket;
/**
*
* @author Dark
*/
public class Mine
{
private static Thread[] threadArray = new Thread[3];
public static void main (String[] args)
{
System.out.println("MINIERA");
System.out.println("In attesa di richieste da parte del fabbro");
//variabile che mi tiene conto dei minatori attivi, max 3
ServerSocket server;
Socket socket;
try
{
//metto il server in ascolto sulla porta 41000
server = new ServerSocket(41000);
//lo metto in attesa perpetua
while (true)
{
socket = server.accept();
minerDispatch(socket);
}
}
catch (IOException ioe)
{
System.out.println(ioe.getMessage());
}
}
//metodo che crea e verifica lo stato dei minatori tramite un array
private static void minerDispatch(Socket socket) throws IOException
{
Message m = new Message (socket);
for(int i = 0; i < 3; i++)
{
if(threadArray[i] == null)
{
threadArray[i] = new Thread(new Miner(socket));
threadArray[i].start();
i = 3;
}
else
{
if(threadArray[i].getState() == Thread.State.TERMINATED)
{
threadArray[i].interrupt();
threadArray[i] = new Thread(new Miner(socket));
threadArray[i].start();
i = 3;
}
else if (i == 3)
m.sendResponse(i);
}
}
}
}
minatore
package Miniera;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintStream;
import java.net.Socket;
import java.util.Random;
import java.util.concurrent.TimeUnit;
/**
*
* @author Dark
*/
public class Miner implements Runnable
{
private BufferedReader reader;
private Socket socket;
private Message m;
private boolean running = true;
private Random rnd = new Random();
private PrintStream writer;
public Miner(Socket socket)
{
this.socket = socket;
}
@Override
public void run ()
{
synchronized(this)
{
while(running)
{
try
{
reader = new BufferedReader(new InputStreamReader(socket.getInputStream()));
writer = new PrintStream(socket.getOutputStream());
m = new Message(socket);
if(m.examineText() != true)
running = false;
else
{
int qty = m.getQty();
int extracted;
for(extracted = 0; extracted < qty;)
{
int ext = extract();
if ((qty - extracted) < ext)
{
extracted = qty;
m.sendResponse((qty - extracted));
running = false;
}
extracted = extracted + ext;
m.sendResponse(ext);
TimeUnit.SECONDS.sleep(ext);
}
}
}
catch (IOException | InterruptedException ioe)
{
System.out.println(ioe.getMessage());
}
}
}
}
private int extract()
{
return rnd.nextInt(5)+1;
}
}
fabbro
package Miniera;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintStream;
import java.io.PrintWriter;
import java.net.Socket;
import java.util.Random;
/**
*
* @author Dark
*/
public class Blacksmith
{
public static void main (String[] args)
{
Random rnd = new Random();
Message m;
Socket socket;
try
{
socket = new Socket ("127.0.0.1", 41000);
m = new Message(socket);
System.out.println("collegamento stabilito");
m.sendRequest(rnd.nextInt(100));
m.recivedRequest();
socket.close();
}
catch (IOException ioe)
{
System.out.println(ioe.getMessage());
}
}
}
per finire message
package Miniera;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintStream;
import java.net.Socket;
/**
*
* @author Kuro
*/
public class Message
{
private String text;
private String command;
private int qty;
private PrintStream writer;
private BufferedReader reader;
private Socket socket;
public Message (Socket socket)
{
this.socket = socket;
}
private void splitText() throws IOException
{
reader = new BufferedReader(new InputStreamReader(socket.getInputStream()));
writer = new PrintStream(socket.getOutputStream());
String[] examine = text.split(":");
command = examine[0];
qty = Integer.parseInt(examine[1]);
}
/**
*
* @return
* @throws IOException
*/
public boolean examineText() throws IOException
{
splitText();
if(command.equals("GET"))
return true;
else
return false;
}
public void sendRequest(int quantity)
{
writer.println("GET:" + quantity);
}
public void sendResponse(int i)
{
if(i < 3)
writer.println("WAIT");
else if (command.equals("GET"))
writer.println("PUT:" + i);
}
public void recivedRequest() throws IOException
{
writer.println(reader.readLine());
}
public int getQty()
{
return qty;
}
}
premetto 2 cose:
1) devo sistemare gli import, ma solo a progetto completo
2) la classe message probabilmente risulta molto confusionaria. lo so, sto cercando di abituarmi a programmare come si deve dividendo il problema il più possibile, e non essendo ancora abituato a questa mentalità, e anche non sapendo benissimo come funziona il discorso socket/thread, probabilmente risulta un attimo incasinato, ma volevo il vostro parere proprio per poter far un po' di luce
sostanzialmente vorrei che la mia classe message facesse:
1) si occupasse di mandare la richiesta del fabbro alla miniera
2) si occupasse di risponde al fabbro di un eventuale carenza di minatori disponibili
3) si occupasse di mandare al fabbro la quantità di materiale estratto dal minatore
mi è stato consigliato di salvarmi il command (put, get, wait) e le varie quantità, per cui ho fatto lo splitText anche se con il solo scopo di verificare che il messaggio del fabbro contenesse GET o meno. potrei farlo meglio, ma prima di rimetterci mano, vorrei appunto il vostro parere