I found this code for playing mp3 in java and I want to stream this in a network using UDP so I want to convert the mp3 file to byte so I can send it using DatagramPacket. What should I convert to do this?
I will be needing to send 60Kbyte of buffer to the datagrampacket.
import javazoom.jl.player.advanced.*;
public class JLayerTest
{
public static void main(String[] args)
{
SoundJLayer soundToPlay = new SoundJLayer("Test.mp3");
soundToPlay.play();
}
}
class SoundJLayer extends PlaybackListener implements Runnable
{
private String filePath;
private AdvancedPlayer player;
private Thread playerThread;
public SoundJLayer(String filePath)
{
this.filePath = filePath;
}
public void play()
{
try
{
String urlAsString = "file:\\C:\\Users\\Lorenz Kyle\\Desktop\\CODES by Lo\\Case 4\\Server\\Mp3MulticastServer\\src\\test.mp3";
this.player = new AdvancedPlayer
(
new java.net.URL(urlAsString).openStream(),
javazoom.jl.player.FactoryRegistry.systemRegistry().createAudioDevice()
);
this.player.setPlayBackListener(this);
this.playerThread = new Thread(this, "AudioPlayerThread");
this.playerThread.start();
}
catch (Exception ex)
{
}
}
// PlaybackListener members
public void playbackStarted(PlaybackEvent playbackEvent)
{
System.out.println("playbackStarted");
}
public void playbackFinished(PlaybackEvent playbackEvent)
{
System.out.println("playbackEnded");
}
// Runnable members
public void run()
{
try
{
this.player.play();
}
catch (javazoom.jl.decoder.JavaLayerException ex)
{
ex.printStackTrace();
}
}
}
Related
I have a ServerSocket Thread that accepts a connection and starts a socket handler. This part seems to be working fine with no memory leaks or high cpu usage. I added a Publisher thread and an observer thread and now, my java program is reporting high CPU usage.
Subject.java:
public interface Subject {
public void attach(Observer o);
public void detach(Observer o);
public void notifyUpdate(Message m);
}
MessagePublisher.java:
public class MessagePublisher extends Thread implements Subject{
private List<Observer> observers = new ArrayList<>();
private boolean readyToPublish = false;
private ConcurrentLinkedQueue<Message> msgHolder;
public MessagePublisher(ConcurrentLinkedQueue<Message> _queue){
this.msgHolder = _queue;
}
#Override
public void attach(Observer o) {
observers.add(o);
}
#Override
public void detach(Observer o) {
observers.remove(o);
}
#Override
public void notifyUpdate(Message m) {
for(Observer o: observers) {
o.update(m);
}
}
public void run(){
this.readyToPublish = true;
while (readyToPublish)
{
try
{
Message _m = (Message)this.msgHolder.poll();
if(!_m.equals(null)){
System.out.println("Polled message: " + _m.getMessage());
System.out.println("Number of subscribers: " + observers.size());
notifyUpdate(_m);
}
}
catch(Exception j) { }
try { sleep(9); }
catch(Exception e) { }
}
EndWork();
}
public void EndWork(){
this.readyToPublish = false;
this.observers.clear();
}
}
Main.java:
public static void main(String[] args) {
// TODO code application logic here
ConcurrentLinkedQueue<Message> msgHolder = new ConcurrentLinkedQueue<Message>();
ServerSocketThread _socketThread = new ServerSocketThread(msgHolder);
_socketThread.start();
MessagePublisher _publisher = new MessagePublisher(msgHolder);
_publisher.start();
UIServerSocketThread _uiSocketThread = new UIServerSocketThread(_publisher);
_uiSocketThread.start();
}
UIServerSocketThread.java:
public class UIServerSocketThread extends Thread{
private ServerSocket objServerSocket;
private Socket objSocket;
private int iPort = 21001;
private FileHandler obj_LogFileHandler;
private Logger obj_Logger;
private int file_size = 8000000;
private int numLogFiles = 20;
private UIClientSocketThread objCltSocket;
private MessagePublisher objPublisher;
private boolean running = false;
public UIServerSocketThread(MessagePublisher _publisher){
this.running = true;
try {
this.obj_LogFileHandler = new FileHandler("uiserver.log.%g", file_size, numLogFiles);
this.obj_LogFileHandler.setFormatter(new SimpleFormatter());
}
catch ( IOException obj_Exception ) {
this.obj_LogFileHandler = null;
}
catch ( SecurityException obj_Exception ) {
this.obj_LogFileHandler = null;
}
this.obj_Logger = null;
if ( this.obj_LogFileHandler != null ) {
this.obj_Logger = Logger.getLogger("eti.logger.uiserver");
this.obj_Logger.addHandler(this.obj_LogFileHandler);
}
try {
this.objServerSocket = new ServerSocket(this.iPort);
} catch(IOException i){
//i.printStackTrace();
this.obj_Logger.info(i.getMessage());
}
this.objPublisher = _publisher;
}
public void run() {
StringBuffer sMsg;
sMsg = new StringBuffer();
while ( this.running ) {
try {
this.objSocket = this.objServerSocket.accept();
} catch(Exception e){
sMsg.append("Error accepting ui socket connection\n");
sMsg.append(e.getMessage());
this.obj_Logger.info(sMsg.toString());
}
try {
this.objCltSocket = new UIClientSocketThread(this.objSocket, this.obj_Logger);
if(!this.objPublisher.equals(null)){
this.obj_Logger.info("Attacing clientObserver");
this.objPublisher.attach(this.objCltSocket);
}
this.objCltSocket.start();
} catch(Exception r) {
sMsg.append("Error \n");
sMsg.append(r.getMessage());
this.obj_Logger.info(sMsg.toString());
}
}
this.objPublisher.EndWork();
stopServerSocketThread();
} // end run
public void stopServerSocketThread() {
try {
this.running = false;
this.objServerSocket.close();
this.objServerSocket = null;
this.obj_Logger.info("Server NOT ACCEPTING Connections!!");
} catch(Exception e ) {
this.obj_Logger.info(e.getMessage());
}
}
}
I am not sure where the issue is. Any help is appreciated.
You have two infinite loops in your application. One is in class MessagePublisher with function run(). And another one is in class UIServerSocketThread. This will cause high CPU usage.
I'm making a multithreaded FTP server in Java and I have a question about to go about handling multiple clients. Right now, I have a Server that looks like this:
public class Server {
private static final int HOST_PORT = 6000;
private ServerSocket serverSocket;
public Server(ServerModel serverModel) throws IOException {
serverSocket = new ServerSocket(HOST_PORT);
}
public void start() {
try {
acceptClients();
} catch (IOException e) {
e.printStackTrace();
}
}
private void acceptClients() throws IOException {
while (true) {
Socket client = serverSocket.accept();
ServerModel serverModel = new ServerModel();
Thread worker = new Thread(new ServerWorker(client, serverModel));
worker.start();
}
}
}
And a ServerWorker object which is responsible for interpreting client commands and responding to them:
public class ServerWorker implements Runnable {
private ServerRemoteHandler serverRemoteHandler;
private ServerModel serverModel;
private static final int GET_CODE = 1;
private static final int PUSH_CODE = 2;
private static final int CHANGE_DIRECTORY_CODE = 3;
private static final int PRINT_WORKING_DIRECTORY_CODE = 4;
private static final int FILE_EXISTS_CODE = 5;
private static final int LIST_FILES_DIRECTORIES_CODE = 6;
private static final int EXIT_CODE = 0;
public ServerWorker(Socket client, ServerModel serverModel) throws IOException {
this.serverModel = serverModel;
try {
serverRemoteHandler = new ServerRemoteHandler(client);
} catch (IOException e) {
e.printStackTrace();
}
}
private void parseCommand() {
int command;
try {
while (true) {
command = serverRemoteHandler.getCommand();
switch (command) {
case CHANGE_DIRECTORY_CODE:
changeDirectory();
break;
case PRINT_WORKING_DIRECTORY_CODE:
printWorkingDirectory();
break;
case FILE_EXISTS_CODE:
fileExists();
break;
case LIST_FILES_DIRECTORIES_CODE:
listFilesDirectories();
break;
case GET_CODE:
pushFile();
break;
case PUSH_CODE:
getFile();
break;
case EXIT_CODE:
exit();
break;
}
}
} catch (IOException e) {
exit();
}
}
private void printWorkingDirectory() throws IOException {
serverRemoteHandler.printWorkingDirectory(serverModel.getCurrentPath());
}
private void changeDirectory() throws IOException {
String fileName = serverRemoteHandler.getFileName();
boolean success = serverModel.changeDirectory(fileName);
serverRemoteHandler.changeDirectory(success);
}
private void fileExists() throws IOException {
String fileName = serverRemoteHandler.getFileName();
serverRemoteHandler.fileExists(serverModel.fileExists(fileName));
}
private void pushFile() throws IOException {
File file = serverModel.getFile(serverRemoteHandler.getFileName());
long fileSize = serverModel.getFileSize(file);
serverRemoteHandler.pushFile(file, fileSize);
}
private void listFilesDirectories() throws IOException {
serverRemoteHandler.listFilesDirectories(serverModel.listFilesDirectories());
}
private void getFile() throws IOException {
String fileName = serverRemoteHandler.getFileName();
File file = new File(serverModel.getCurrentPath() + File.separator + fileName);
serverRemoteHandler.getFile(file);
}
private void exit() {
serverRemoteHandler.exit();
}
#Override
public void run() {
while (true) {
parseCommand();
}
}
}
Each ServerWorker has an Object called RemoteHandler whose job is to send and receive information from the streams. My questions are regarding this line:
Thread worker = new Thread(new ServerWorker(client, serverModel));
Is this thread safe? Is this a good way of implementing it? Thank you.
Yes it is threadsafe. Everything in that line is method-local, so it is only accessible by the current thread, and then the worker thread starts while this one loops and gets a new set of values for these variables.
(That doesn't imply the entire program is thread-safe, of course.)
I'm trying to get an object from the server, but it does not work.
Relevant section from the server (By Debug I see that he is really sending the correct object):
public static void main(String[] args){
launch(args);
}
public void start(Stage primaryStage) {
BorderPane mainPane = new BorderPane();
mainPane.setStyle("-fx-border-color: black;");
mainPane.setPadding(new Insets(5,5,5,5));
GridPane gridPane = new GridPane();
gridPane.setPadding(new Insets(5,5,5,5));
gridPane.add(lblStatus,0,1);
gridPane.add(lblDate,0,2);
mainPane.setTop(gridPane);
createTableView();
mainPane.setCenter(tableView);
Scene scene = new Scene(mainPane, 700, 250);
primaryStage.setTitle("Server"); // Set the window title
primaryStage.setScene(scene); // Place the scene in the window
primaryStage.show(); // Display the window
primaryStage.setAlwaysOnTop(true);
primaryStage.setOnCloseRequest(
new EventHandler<WindowEvent>(){
public void handle(WindowEvent event) {
try {
Platform.exit();
System.exit(0);
serverSocket.close();
socket.close();
}
catch(SocketException ex){
try {
socket.close();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
catch (IOException e) {
// TODO Auto-generated catch block
Platform.exit();
System.exit(0);
}
}
});
connectToDB();
connectionDate=new Date();
Platform.runLater(() ->lblDate.setText(("Server started at \t"+connectionDate)));
Platform.runLater(() ->lblStatus.setText(connectionStatus));
new Thread( () ->
{
try{
// Create a server socket
serverSocket = new ServerSocket(8000);
while (true){
// Listen for a connection request
socket = serverSocket.accept();
this.clientNo++;
clientRequest clientDetails = new clientRequest(clientNo, new Date(), "New Clinet");
addRowToServerTable(clientDetails);
new Thread(new HandleAClient(socket)).start();
}
}
catch(SocketException ex){
}
catch(IOException ex){
}
}).start();
}
/** Connect to DB */
private void connectToDB(){
// Connection to the database
try{
Class.forName(driver); // Load the JDBC driver
System.out.println("Driver Loaded");
connection = DriverManager.getConnection(url, username, password); // Establish a connection
System.out.println("Connected to " + url);
connectionStatus = "Connected to \t" + url;
}
catch (java.lang.Exception ex){
ex.printStackTrace();
connectionStatus = ex.toString();
}
}
// Define the thread class for handling new connection
class HandleAClient implements Runnable{
private Socket socket; // A connected socket
/** Construct a thread */
public HandleAClient(Socket socket){
this.socket = socket;
}
/** Run a thread */
public void run(){
try{
// Create data input and output streams
ObjectOutputStream outputToClient = new ObjectOutputStream(
socket.getOutputStream());
DataInputStream inputFromClient = new DataInputStream(
socket.getInputStream());
// Continuously serve the client
while (true){
// Receive sql from the client
String sql = inputFromClient.readUTF();
clientRequest clientDetails = new clientRequest(clientNo, new Date(),"New Query");
addRowToServerTable(clientDetails);
// Execute SQL
Object[] rows = executeSQL(sql);
outputToClient.writeObject(rows);
}
}
catch(SocketException ex){
try{
serverSocket.close();
//socket.close();
}
catch (IOException e){
}
}
catch(IOException ex){
}
}
Relevant section from the client (Probably the mistake on the client, when it receives the object he jumps line ".start ();" Of the Thread.):
private void connectToServer(){
try{
// Create a socket to connect to the server
socket = new Socket(host, 8000);
// Create an input stream to receive Object from the server
fromServer = new ObjectInputStream(socket.getInputStream());
// Create an output stream to send data to the server
toServer = new DataOutputStream(socket.getOutputStream());
}
catch (Exception ex){
ex.printStackTrace();
}
}
private void sendAndGetFromServer(String sqlQuery){
new Thread(() ->{
try{
System.out.println("a1");
// Send sql query to server
toServer.writeUTF(sqlQuery);
//toServer.flush();
// Get notification from the server
Student[] rows = (Student[])fromServer.readObject();
setRowsInTable(rows);
}
catch(SocketException ex){
try{
socket.close();
}
catch (IOException e){
}
}
catch (Exception ex){
}
}).start();
I tried to separate into two Thread (One Input and other Output in Server and client) according to the answers I read here --- but it didn't help.
Also tried to change the order of Input and Output --- without success.
No errors!
The client don't get the object.
What's the problem here?
Edit. Student class:
public class Student implements Externalizable
{
private final SimpleIntegerProperty ID;
private final SimpleStringProperty firstName;
private final SimpleStringProperty lastName;
private final SimpleStringProperty address;
private final SimpleObjectProperty<Date> birthDate;
private final SimpleStringProperty department;
private final SimpleIntegerProperty pointsAmount;
private final SimpleObjectProperty<Date> startStudyingDate;
private final SimpleIntegerProperty failedAmount;
private final SimpleDoubleProperty average;
private final SimpleIntegerProperty lavelByGrade;
private final SimpleStringProperty pic;
public Student(int ID, String firstName, String lastName, String address,
Date birthDate, String department,
int pointsAmount, Date startStudyingDate, int failedAmount,
double average, int lavelByGrade, String pic){
this.ID= new SimpleIntegerProperty(ID);
this.firstName= new SimpleStringProperty(firstName);
this.lastName= new SimpleStringProperty(lastName);
this.address= new SimpleStringProperty(address);
this.birthDate= new SimpleObjectProperty<Date>(birthDate);
this.department= new SimpleStringProperty(department);
this.pointsAmount= new SimpleIntegerProperty(pointsAmount);
this.startStudyingDate= new SimpleObjectProperty<Date>(startStudyingDate);
this.failedAmount= new SimpleIntegerProperty(failedAmount);
this.average= new SimpleDoubleProperty(average);
this.lavelByGrade= new SimpleIntegerProperty(lavelByGrade);
this.pic = new SimpleStringProperty(pic);
}
public int getID() {
return ID.get();
}
public void setID(int ID) {
this.ID.set(ID);
}
public String getFirstName() {
return firstName.get();
}
public void setFirstName(String firstName) {
this.firstName.set(firstName);
}
public String getLastName() {
return lastName.get();
}
public void setLastName(String lastName) {
this.lastName.set(lastName);
}
public String getAddress() {
return address.get();
}
public void setAddress(String address) {
this.address.set(address);
}
public Date getBirthDate() {
return birthDate.get();
}
public void setBirthDate(Date birthDate) {
this.birthDate.set(birthDate);
}
public String getDepartment() {
return department.get();
}
public void setDepartment(String department) {
this.department.set(department);
}
public int getPointsAmount() {
return pointsAmount.get();
}
public void setPointsAmount(int pointsAmount) {
this.pointsAmount.set(pointsAmount);
}
public Date getStartStudyingDate() {
return startStudyingDate.get();
}
public void setStartStudyingDate(Date startStudyingDate) {
this.startStudyingDate.set(startStudyingDate);
}
public int getFailedAmount() {
return failedAmount.get();
}
public void setFailedAmount(int failedAmount) {
this.failedAmount.set(failedAmount);
}
public double getAverage() {
return average.get();
}
public void setAverage(Double average) {
this.average.set(average);
}
public int getLavelByGrade() {
return lavelByGrade.get();
}
public void setLavelByGrade(int lavelByGrade) {
this.lavelByGrade.set(lavelByGrade);
}
public String getPic() {
return pic.get();
}
public void setPic(String pic) {
this.pic.set(pic);
}
#Override
public void readExternal(ObjectInput in) throws IOException,
ClassNotFoundException {
setID(in.readInt());
setFirstName((String)in.readObject());
setLastName((String)in.readObject());
setAddress((String)in.readObject());
setBirthDate((Date)in.readObject());
setDepartment((String)in.readObject());
setPointsAmount(in.readInt());
setStartStudyingDate((Date)in.readObject());
setFailedAmount(in.readInt());
setAverage(in.readDouble());
setLavelByGrade(in.readInt());
setPic((String)in.readObject());
}
#Override
public void writeExternal(ObjectOutput out) throws IOException {
out.writeInt(getID());
out.writeObject(getFirstName());
out.writeObject(getLastName());
out.writeObject(getAddress());
out.writeObject(getBirthDate());
out.writeObject(getDepartment());
out.writeInt(getPointsAmount());
out.writeObject(getStartStudyingDate());
out.writeInt(getFailedAmount());
out.writeDouble(getAverage());
out.writeInt(getLavelByGrade());
out.writeObject(getPic());
}
}
JavaFX properties are not Serializable. So if you try to serialize an object that uses JavaFX properties for its state, you will get an exception.
You have a couple of options here. One is simply to not use Java object serialization, but some other serialization technique, such as representing the object with JSON.
The other option is to implement Externalizable instead of Serializable. Externalizable is a subinterface of Serializable in which you define your own process for serializing and deserializing the data. In particular, instead of serializing the JavaFX properties themselves, just serialize their contents.
A simple example:
import java.io.Externalizable ;
import java.io.IOException ;
import java.io.ObjectInput ;
import java.io.ObjectOutput ;
import javafx.beans.property.IntegerProperty ;
import javafx.beans.property.SimpleIntegerProperty ;
import javafx.beans.property.SimpleStringProperty ;
import javafx.beans.property.StringProperty ;
public class Person implements Externalizable {
private final StringProperty name = new SimpleStringProperty();
private final IntegerProperty id = new SimpleIntegerProperty();
public StringProperty nameProperty() {
return name ;
}
public final String getName() {
return nameProperty().get();
}
public final void setName(String name) {
nameProperty().set(name);
}
public IntegerProperty idProperty() {
return id ;
}
public final int getId() {
return idProperty().get();
}
public final void setId(int id) {
idProperty().set(id);
}
// important: must have a no-arg constructor:
public Person() { }
public Person(int id, String name) {
setId(id);
setName(name);
}
#Override
public void writeExternal(ObjectOutput out) throws IOException {
// write id then name
// note we write the contents of the properties, not the properties
// themselves, as the properties are not serializable:
out.writeInt(getId());
out.writeObject(getName());
}
#Override
public void readExternal(ObjectInput in) throws IOException, ClassNotFoundException {
// read data back in same order:
setId(in.readInt());
setName((String)in.readObject());
}
}
Note that this class has a pretty simple structure, so it's easy to implement these two methods. For more complex objects - particularly those which may potentially have circular references - you need to work a bit harder.
Since the class defined above implements Externalizable, it also implements Serializable, and can be serialized in the usual way:
ObjectOutputStream oos = ... ;
oos.writeObject(new Person(007, "James Bond"));
Read my blog post on JavaFX beans and JPA for more.
Try with this post, search part with following text and Externalizable: For quite a long time, I thought the lack of support for Serialization from JavaFX properties really prevented them from being used in any server-side capacity.
http://www.marshall.edu/genomicjava/2014/05/09/one-bean-to-bind-them-all/
https://gist.github.com/james-d/e485ac525c71e20bb453
I'm trying to use a function to open an arraylist of objects with fileIO but right now i'm stuck. I think there is something wrong with my setter function. (The file test.txt already exists)
The following classes I'm using to get the fileio function to work
Paslijst
public class Paslijst implements Serializable {
private ArrayList<Pas> paslijst;
public ArrayList<Pas> setPaslijst(ArrayList<Pas> paslijst){
this.paslijst = paslijst;
return paslijst;
}
FileIOPas
// This function opens a file
public Paslijst openen(String filenaam)
throws IOException, ClassNotFoundException {
FileInputStream fileInputStream = new FileInputStream(filenaam);
ObjectInputStream objectInputStream = new ObjectInputStream(fileInputStream);
return (Paslijst) objectInputStream.readObject();
}
Main
public static void main(String[] args) {
FileIOPas fileiopas = new FileIOPas();
Paslijst paslijst = new Paslijst();
try {
paslijst.setPaslijst(fileiopas.openen("test.txt"));
}
catch (IOException e) {
System.out.println(" IO openen mislukt, want: " + e.toString());
}
catch (ClassNotFoundException e) {
System.out.println("class not found: " + e.toString());
}
}
You were passing wrong arguments in paslijst.setPaslijst().I have edited your class may this could Help.
public class Main {
public static void main(String[] args) {
FileIOPas fileiopas = new FileIOPas();
Paslijst paslijst = new Paslijst();
paslijst.setPaslijst(fileiopas.openen("test.txt"));
}
}
public class FileIOPas {
public ArrayList<Pas> openen(String filenaam) {
try (FileInputStream fileInputStream = new FileInputStream(filenaam);
ObjectInputStream objectInputStream = new ObjectInputStream(
fileInputStream);) {
return (ArrayList<Pas>) objectInputStream.readObject();
} catch (Exception exception) {
exception.printStackTrace();
}
return null;
}
}
public class Paslijst implements Serializable {
private ArrayList<Pas> paslijst;
public ArrayList<Pas> getPaslijst() {
return paslijst;
}
public void setPaslijst(ArrayList<Pas> paslijst) {
this.paslijst = paslijst;
}
}
I am desperate...I'm working all the day on a program but I didn't resolve my issue about thread cuncurrency.Please help me.
I have this class which is a generic Item.My problem is when this object enters in wait() it doesn't wake up anymore even if I call on the same object the method putItemToWork().I would know if there is a mistake on the code about cuncurrency because really I don't understand where I make mistakes...
Item Class
import java.io.*;
public class Item implements Serializable
{
private String id;
private String category;
private String machine;
private boolean isWorked;
private String mchTemp = null;
public Item(String id,String category,String machine,boolean isWorked)
{
this.id = id;
this.category = category;
this.machine = machine;
this.isWorked = isWorked;
}
public synchronized void putItemToWork(String id_machine)
{
try
{
System.out.println("Working the item...");
Thread.sleep((long)(1+Math.random()*10000));
}
catch(InterruptedException ie) {ie.printStackTrace(); }
mchTemp = id_machine;
isWorked = true;
notify();
}
public synchronized String getWorkedItem()
{
if(mchTemp == null)
{
try
{
wait();
}
catch(InterruptedException ie) {ie.printStackTrace(); }
}
return mchTemp;
}
public String getId()
{
return this.id;
}
public String getCategory()
{
return this.category;
}
public String getMachine()
{
return this.machine;
}
public boolean isWorked()
{
return this.isWorked;
}
}
}
ServerMultiThread
import java.io.*;
import java.util.*;
import java.net.*;
import javax.swing.SwingUtilities;
import javax.swing.JTextArea;
public class ServerMultiThread implements Runnable
{
Socket socket;
private ServerSocket serverSocket;
private LinkedList<Item> itemsList;
private LinkedList<Machine> machinesList;
private static final boolean listening = true;
private JTextArea output;
public ServerMultiThread(LinkedList<Item> itemsList,LinkedList<Machine> machinesList,JTextArea output)
{
this.itemsList = itemsList;
this.machinesList = machinesList;
this.output = output;
try
{
this.serverSocket = new ServerSocket(8090);
}
catch(IOException ioe){ioe.printStackTrace(); }
new Thread(this, "Server").start();
}
#Override
public void run()
{
Item itemTemp = null;
SwingUtilities.invokeLater(new Runnable(){#Override public void run(){output.append("Server in run!\n");}});
while(listening)
{
try
{
SwingUtilities.invokeLater(new Runnable(){public void run(){output.append("Waiting for incoming connection...\n");}});
socket = serverSocket.accept();
SwingUtilities.invokeLater(new Runnable(){#Override public void run(){output.append("Connected to: "+socket.getInetAddress()+":"+socket.getPort()+"!\n");}});
ObjectOutputStream ous = new ObjectOutputStream(socket.getOutputStream());
synchronized(itemsList)
{
for(Item item : itemsList)
{
if(!item.isWorked())
{
itemTemp = item;
break;
}
}
new ItemHandler(itemTemp,ous,output);
}
}
catch(IOException ioe) {ioe.printStackTrace(); }
}
}
}
ItemHandler
import java.io.*;
import java.util.LinkedList;
import javax.swing.JTextArea;
import javax.swing.SwingUtilities;
public class ItemHandler implements Runnable
{
String id_machine;
private Item item;
private ObjectOutputStream ous;
//private ObjectInputStream ois;
private JTextArea output;
public ItemHandler(Item item,ObjectOutputStream ous,JTextArea output)
{
this.item = item;
this.ous = ous;
//this.ois = ois;
this.output = output;
new Thread(this).start();
}
#Override
public void run()
{
try
{
ous.writeObject(item);
SwingUtilities.invokeLater(new Runnable(){public void run(){output.append("Item Handler "+item.getId()+ " in run!\n");}});
id_machine = item.getWorkedItem();
SwingUtilities.invokeLater(new Runnable(){public void run(){output.append("The item "+item.getId()+" was correctly worked by "+id_machine);}});
//System.out.println("The item "+workedItem.getId()+" was correctly worked by "+workedItem.getMachine());
}
catch(IOException ioe){ioe.printStackTrace();}
}
}
MachineApp
import java.io.*;
import java.net.*;
public class MachineApp
{
private Socket socket;
private String id_machine;
public MachineApp(String id_machine)
{
this.id_machine = id_machine;
try
{
this.socket = new Socket("localhost",8090);
System.out.println("Estabilished connection to main server!");
}
catch(UnknownHostException uhe) {uhe.printStackTrace();}
catch(IOException ioe) {ioe.printStackTrace(); }
execution();
}
private void execution()
{
try
{
//ObjectOutputStream ous = new ObjectOutputStream(socket.getOutputStream());
ObjectInputStream ois = new ObjectInputStream(socket.getInputStream());
Item item = (Item) ois.readObject();
item.putItemToWork(id_machine);
System.out.println("Item Worked!");
}
catch(ClassNotFoundException cnfe) {cnfe.printStackTrace(); }
catch(IOException ioe) {ioe.printStackTrace(); }
}
public static void main(String[] args)
{
MachineApp machineApp = new MachineApp(args[0]);
}
}
For me your code works just fine. Are you calling wait/notify from different threads:
public static void main(String[] args) {
final Item item = new Item("id", "cat", "mach", false);
Thread retrievalThread = new Thread(new Runnable() {
#Override
public void run() {
item.getWorkedItem();
}
});
Thread puttingThread = new Thread(new Runnable() {
#Override
public void run() {
item.putItemToWork("id");
}
});
retrievalThread.start();
puttingThread.start();
}
EDIT: after client code was added to question:
I could be wrong but you're sending item object via socket and then trying to call getWorkedItem on it. It doesn't work this way because once you've send item thru network object on the other side (even if it's happening in one JVM) that will be different object. Therefore calling notify on it won't trigger wake up from wait.
How to solve it? Well, you can add some kind of query interface to your server code so you could query which items were worked.
If it's no homework, or learning exercise I think that Hadoop can be good fit for your needs
For starters, you're going to need to make mchTemp volatile, because you're writing to this field in one thread, and reading it from another. Without volatile, changes made in one thread may not be visible in another tread.
private volatile String mchTemp = null;