Home arrow static arrow Java Programming [Archive] - Threading and Synchronizing
Warning: Creating default object from empty value in /www/htdocs/w008deb8/wiki/components/com_staticxt/staticxt.php on line 51
Java Programming [Archive] - Threading and Synchronizing
This topic has 18 replies on 2 pages.    1 | 2 | Next »

Posts:18
Registered: 3/10/04
Threading and Synchronizing  
Jun 22, 2004 10:49 AM



 
Hello, I am having trouble with my program. It seems as though the synchronization is incorrect when I update the Nicks vector. Please help me.

The server side (which I think is the problem):
import java.io.*;import java.net.*;import java.util.Vector; public class Server{	private int Port = 1024, MaxClients = 1024;	private ServerSocket Server;	private Vector Clients, Nicks;	private Server()	{		try		{			BufferedReader In = new BufferedReader(new InputStreamReader(System.in));			System.out.print("Enter the port you would like to use for your server: ");			String CurrentLine = In.readLine();			if(!CurrentLine.equals(""))				Port = Integer.parseInt(CurrentLine);			System.out.print("Enter the maximum number of clients you would like to have for your server: ");			CurrentLine = In.readLine();			if(!CurrentLine.equals(""))				MaxClients = Integer.parseInt(CurrentLine);			System.out.println("Server started.");			Server = new ServerSocket(Port, MaxClients);			Clients = new Vector();			Nicks = new Vector();			while(true)				Clients.addElement(new ThreadedSocket(Server.accept()));		}		catch(Throwable t) {}	}	public static void main(String[] args)	{		try		{			new Server();		}		catch(Throwable t) {}	}	private synchronized void Echo(Object Message)	{		try		{			System.out.println(Message);			for(int ClientNumber = 0; ClientNumber < Clients.size(); ClientNumber++)				((ThreadedSocket)Clients.elementAt(ClientNumber)).Out.writeObject(Message);		}		catch(Throwable t) {}	}	private class ThreadedSocket extends Thread	{		public Socket Client;		public ObjectOutputStream Out;		public ObjectInputStream In;		public ThreadedSocket(Socket SocketChosen)		{			try			{				Client = SocketChosen;				Out = new ObjectOutputStream(Client.getOutputStream());				In = new ObjectInputStream(Client.getInputStream());				start();			}			catch(Throwable t) {}		}		public void run()		{			try			{				String Nick = "", Message = "";				boolean Flag = true, Check = true;				while(Client.isConnected())				{					try					{						Message = In.readObject().toString();						if(Flag)						{							if(Nicks.contains(Nick = Message))							{								Out.writeObject("Nick has been taken. Try another one.");								Check = false;								break;							}							synchronized(Nicks)							{								Nicks.addElement(Nick);							}							Echo(Nicks);							Flag = false;						}						else							Echo(Message);					}					catch(SocketException e) {break;}				}				if(Check)				{					synchronized(Nicks)					{						Nicks.removeElement(Nick);					}					Echo(Nicks);				}				Client.close();				Out.close();				In.close();			}			catch(Throwable t) {t.printStackTrace();}		}	}}
And the client (which I doubt is the problem):
import java.awt.BorderLayout;import java.awt.event.*;import java.io.*;import java.net.*;import java.util.Vector;import javax.swing.*;import javax.swing.border.*; public class Client extends JFrame{	private int Port = 1024;	private String IP = "127.0.0.1", Nick;	private JList List;	private JTextArea TextArea;	private JTextField TextField;	private Socket Client;	private ObjectOutputStream Out;	private ObjectInputStream In;	private Client()	{		super("Kaps's Chat Client");		try		{			BufferedReader Temp = new BufferedReader(new InputStreamReader(System.in));			System.out.print("Enter the IP of the server you would like to join: ");			String CurrentLine = Temp.readLine();			if(!CurrentLine.equals(""))				IP = CurrentLine;			System.out.print("Enter the port of the server you would like to join: ");			CurrentLine = Temp.readLine();			if(!CurrentLine.equals(""))				Port = Integer.parseInt(CurrentLine);			System.out.print("Enter your nick for the server you would like to join: ");			Nick = Temp.readLine();			System.out.println("Client started.");			List = new JList();			TextArea = new JTextArea();			TextField = new JTextField();			JPanel Panel = new JPanel(new BorderLayout()), PeoplePanel = new JPanel(new BorderLayout());			TextArea.setEditable(false);			TextField.addActionListener(new ActionListener()			{				public void actionPerformed(ActionEvent e)				{					try					{						if(!TextField.getText().equals(""))						{							Out.writeObject(Nick + ": " + TextField.getText());							TextField.setText("");						}					}					catch(Throwable t) {}				}			});			PeoplePanel.add(new JScrollPane(TextArea), BorderLayout.CENTER);			PeoplePanel.add(new JScrollPane(List), BorderLayout.EAST);			Panel.add(PeoplePanel, BorderLayout.CENTER);			Panel.add(TextField, BorderLayout.SOUTH);			Panel.setBorder(new TitledBorder(new EtchedBorder(), "Kaps's Chat Client"));			addWindowListener(new WindowAdapter()			{				public void windowClosing(WindowEvent e)				{					try					{						Out.writeObject("Server: " + Nick + " [" + InetAddress.getLocalHost().getHostName() + "] has quit this server.");						Client.close();						Out.close();						In.close();						System.exit(0);					}					catch(Throwable t) {}				}			});			getContentPane().add(Panel);			setSize(640, 480);			setVisible(true);			Client = new Socket(IP, Port);			Out = new ObjectOutputStream(Client.getOutputStream());			In = new ObjectInputStream(Client.getInputStream());			Out.writeObject(Nick);			Out.writeObject("Server: " + Nick + " [" + InetAddress.getLocalHost().getHostName() + "] has joined this server.");			while(true)			{				try				{					Object Message = In.readObject();					if(Message instanceof Vector)						List.setListData((Vector)Message);					if(Message instanceof String)						TextArea.append(Message.toString() + "\n");				}				catch(SocketException e) {break;}			}			getWindowListeners()[0].windowClosing(null);		}		catch(Throwable t) {t.printStackTrace();}	}	public static void main(String[] args)	{		try		{			new Client();		}		catch(Throwable t) {}	}}
 

Posts:37,103
Registered: 3/30/99
Re: Threading and Synchronizing  
Jun 22, 2004 10:51 AM (reply 1 of 18)



 
What exactly is the problem? What do you expect to happen and what are you observing instead?
 

Posts:18
Registered: 3/10/04
Re: Threading and Synchronizing  
Jun 22, 2004 10:52 AM (reply 2 of 18)



 
Well, the client's list of nicknames doesn't update properly.
 

Posts:37,103
Registered: 3/30/99
Re: Threading and Synchronizing  
Jun 22, 2004 11:00 AM (reply 3 of 18)



 
Well, the client's list of nicknames doesn't update
properly.

Meaning what? It doesn't get anything? It gets the same thing multiple times? It only keeps the last one? The first one? The odd-numbered ones?

Details, man, details...
 

Posts:18
Registered: 3/10/04
Re: Threading and Synchronizing  
Jun 22, 2004 11:04 AM (reply 4 of 18)



 
OK, the nickname list is the same from the time the client connects to the server. It should update, but it doesn't for synchronization issues i believe.
 

Posts:342
Registered: 5/22/98
Re: Threading and Synchronizing  
Jun 22, 2004 11:06 AM (reply 5 of 18)



 
Don't know if these are causing your problem but I would do the following:

Server:
In the Echo method, synchronize the Message and the Clients. You are iterating over the Clients Vector, so it needs synchronizing. The message is sometimes the Nicks list, so you need to synchronize the message to prevent the Nicks list from being changed while you are echoing it.

Graeme
 

Posts:1,183
Registered: 1/23/02
Re: Threading and Synchronizing  
Jun 22, 2004 11:11 AM (reply 6 of 18)



 
For a start, don't do this (I'm sure you know why):

catch(Throwable t) {}
 

Posts:37,103
Registered: 3/30/99
Re: Threading and Synchronizing  
Jun 22, 2004 11:15 AM (reply 7 of 18)



 
First of all, make sure you're not smothering any exceptions. Wherever you have this
catch(Throwable t) {} 
put in a call to printStackTrace().
 

Posts:6,750
Registered: 1/25/04
Re: Threading and Synchronizing  
Jun 22, 2004 11:15 AM (reply 8 of 18)



 
For a start, don't do this (I'm sure you know why):

catch(Throwable t) {}

If he's doing it, I wouldn't be so sure he knows why it's a bad thing.
 

Posts:18
Registered: 3/10/04
Re: Threading and Synchronizing  
Jun 22, 2004 1:55 PM (reply 9 of 18)



 
I deleted the printStackTrace() call before posting it, so my source code on my computer still has the call. I understand that the call will let me see what errors and exceptions happened where and how. I just do not include it because I do not want it to interfere with your help, not mine.
 

Posts:37,103
Registered: 3/30/99
Re: Threading and Synchronizing  
Jun 22, 2004 2:10 PM (reply 10 of 18)



 
Is your code also printing in the client where you read an object?
catch(SocketException e) {break;}


Your code is kind of hard to follow, and the GUI stuff is too mixed up with the non-GUI stuff. In the absence of somebody offering something more specific, what I can suggest is to separate out the GUI stuff, and make it work without it first. Then add the GUI as a layer on top of the communications. Put a bunch of print statements in so you can see which code is getting executed and what various values are.
 

Posts:18
Registered: 3/10/04
Re: Threading and Synchronizing  
Jun 22, 2004 2:17 PM (reply 11 of 18)



 
Listen, I see what the problem is but I do not know how to fix it. It is the server, where there is absolutely no GUI whatsoever. It is where I add and remove nicks to the Nicks vector. The problem is there are multiple ThreadedSockets running at the same time, making it hard for it to be synchronized correctly. I just need to know how to do that correctly.
 

Posts:1,183
Registered: 1/23/02
Re: Threading and Synchronizing  
Jun 22, 2004 2:39 PM (reply 12 of 18)



 
Listen, I see what the problem is but I do not know how to fix it

If you knew what the problem was you wouldn't have to ask the forum - the fix would be automatic. The reason why you, I, jverd and everyone else here can't tell what's wrong is becuase your program is not very well structured. Please do consider the suggestions to add print statements to see what is happening during execution.
 

Posts:18
Registered: 3/10/04
Re: Threading and Synchronizing  
Jun 22, 2004 2:43 PM (reply 13 of 18)



 
As I have said, I have done that already. In the client, when there is more than one person connected, it shows a static Nicks vector in the console, meaning there is something wrong with the updating of that Vector. Please, do not say that I do not add print statements because I have said countless times that I did, I just deleted them to make it easier for you.
 

Posts:1,183
Registered: 1/23/02
Re: Threading and Synchronizing  
Jun 22, 2004 2:46 PM (reply 14 of 18)



 
In response to you question of how to synchronize access to Nicks. You each thread needs to synchronize on the same monitor while it's performing the operation on Nicks. The monitor of Nicks itself is the obvious choice for that. You already synchronize on it in a couple of places but the scope is too narrow.

For example you code goes "if Nicks contains ... synchronize { add to Nicks }". There's no guarantee that between your check for "contains" and you adding a new element another thread has not changed Nicks. The correct approach woul be "synchronize { if Nicks contains ... else add to Nicks }". Also you need to wrap operations such as writing Nicks to the sockt in synchronized blocks (you don't want someone to modify Nicks while you're writing it out).

I do belive you'll find the problem is deeper that misssynchronization though.
 
This topic has 18 replies on 2 pages.    1 | 2 | Next »