I have this simple server-socket application using TCP that allows multiple clients to connect to a server and store and retrieve data from an ArrayList. Everytime a client connection is accepted into the server, a new thread is created to handle the client activity, and since all clients must interact with the same data structure I decided to create a static ArrayList as follows:
public class Repository {
private static List<String> data;
public static synchronized void insert(String value){
if(data == null){
data = new ArrayList<>();
}
data.add(value);
}
public static synchronized List<String> getData() {
if(data == null){
data = new ArrayList<>();
}
return data;
}
}
So, everytime a client inserts a value or reads the list they just call Repository.insert(value)
or Repository.getData()
from their respective threads.
My questions are:
- Making these methods synchronized is enough to make the operations thread safe?
- Are there any architectural or performance issues with this static List thing? I could also create an instance of the List in the server class (the one that accepts the connections) and send a reference via contructor to the Threads instead of using the static. Is this any better?
- Can
Collections.synchronizedList()
add any value to such a simple task? Is it necessary? - How could I test the thread-safety in this scenario? I tried just creating multiple clients and make them access the data and everything seems to work, but I'm just not convinced... Here is a short snippet of this test:
IntStream.range(0,10).forEach(i->{
Client client = new Client();
client.ConnectToServer();
try {
client.SendMessage("Hello from client "+i);
} catch (IOException e) {
e.printStackTrace();
}});
//assertions on the size of the array
Thanks in advance! :)