1

Lets take an example:

public class DBServer {
static boolean listening = false;
private static ServerSocket serverSocket = null;
private static Socket clientSocket = null;
static List<ClientThread> users = null;

public static void main(String[] args) {
    users= new LinkedList();
    int portNumber = 0;//some valid port number
    System.out.println("Now using port number=" + portNumber);
    try {
        serverSocket = new ServerSocket(portNumber);
    } catch (IOException e) {
        System.out.println(e);
    }

    while (listening) {
        try {
            System.out.println("Number of users connected: " + users.size());
            clientSocket = serverSocket.accept();
            System.out.println("Someone just joined.");
            ClientThread ct= new ClientThread(clientSocket);
            users.add(ct);
            ct.start();
        }catch (IOException e) {
            System.out.println(e);
        }
    }
}
}//End of class

public class ClientThread extends Thread {
    int c = 0;
    //some other variables
    ClientThread(Socket s){
        this.clientSocket= s; 
    }
    void doSomething(){
        ClientThread ct = DBServer.users.get(0);
        synchronized(ct){
            ct.c++;//or some other operation on c
        }
    }
    void method2(){
        c++;//or some other operation on c
    }

    //some other methods

    public void run(){
    //some never ending logic that decides which method is being called
    }
}//End of class

Let's assume that there are 3 users(User 0, User 1, User 2) connected to the server at a given time.
User 1 obtains the intrinsic lock for the object of User 0. It is certain that User 2 can't obtain the lock for User 0 while User 1 still posses it. Can User 0 himself change the value of c using method2() while the lock is held by User 1? If so, is there a way to make variable c synchronized between the thread owning it and other threads?

Akash Agarwal
  • 2,326
  • 1
  • 27
  • 57
  • No. It just prevents another thread synchronising on the same variable. – Andy Turner Feb 05 '16 at 06:53
  • @AndyTurner That sucks, could you confirm this post's answer by Jon Skeet would solve my purpose? http://stackoverflow.com/questions/5861894/how-to-synchronize-or-lock-upon-variables-in-java – Akash Agarwal Feb 05 '16 at 06:59
  • for the love of emperor gaben : PLEASE get rid of the `while(true)` deadlock, thats the worst piece of code imaginable and it *never* serves any purpose other than lazyness – specializt Feb 05 '16 at 06:59
  • @specializt I don't see the problem in it, it's a server which is supposed to stay alive for future connections. Could you please tell me where am I going wrong and what's the workaround? – Akash Agarwal Feb 05 '16 at 07:00
  • "staying alive for future connections" is no reason to create a deadlock - at all. Simply put a flag in there which can be set from other threads - the actual usage of that flag may be added sometime but you really **need** to avoid deadlocks like that, they will **always** break your application at some point, no matter how many `break` statements you might insert - the reason for that is ... *complicated* and would take several pages of explanations but it certainly exists. Use a `static` `AtomicBoolean`, for instance ... its not hard. – specializt Feb 05 '16 at 07:04
  • @specializt I'll surely consider your advice, thanks for that. I still don't see a reason to turn off the server at any given point of its execution though unless I'm upgrading it. I'd be obliged if you could link me to a post where I could find my answer. – Akash Agarwal Feb 05 '16 at 07:07
  • Applications of any kind **need** to be stoppable or else you're ... not writing actual applications - `while(true)` creates logical paths which cannot be halted. Applications like that usually are considered "bad" since they need to be terminated forcefully - which can result in loss of data and in very exotic cases even hardware damage (!). As a future software developer your primary goal should be to write "good" code, create reliable, well-written software. – specializt Feb 05 '16 at 07:10
  • @specializt Thankyou for that insight! I'll change that right away! – Akash Agarwal Feb 05 '16 at 07:11
  • *Very* strange design here. There is absolutely no way that `clientSocket` should be static, or that a thread should be changing a variable in another thread other than via a setter, and probably not even then. – user207421 Feb 05 '16 at 07:52

2 Answers2

0

So for your following question //If so, is there a way to make variable c synchronized?

Go for AtomicInteger which will prevent the race condition,

AtomicInteger c;

arunan
  • 922
  • 1
  • 17
  • 25
0

you can make C a static variable of class DBServer that way all threads will have access to it.

now, that will require you to change method2() to be synchronized.

and if you do that, to answer your question under these new terms, user 0 will not be able to change variable C while its under the control of user 1.

HazirBot
  • 323
  • 2
  • 14
  • In my real code, there is an `ObjectOutputStream`'s object that needs to belong to that thread which I referred to as `c` for simplicity here, so I can't really put `c` in `DBServer`. – Akash Agarwal Feb 05 '16 at 07:43
  • why do two threads need access to the same outputstream? to my understanding each thread should have access to a different outputstream connected to it's own socket. – HazirBot Feb 05 '16 at 07:47
  • It's actually because I want to send a message from one client to another, to save some time, I want to use this method. – Akash Agarwal Feb 05 '16 at 07:48
  • @AkashAggarwal that's some bad programming mate, users should contact one another Through the server and not p2p. unless completely intentional. you should make an ArrayList of users that saves each user's outputStream and and perhaps a user name and iterate over that – HazirBot Feb 05 '16 at 07:50
  • also, to message user 1 from user 0 you'll need his InputStream – HazirBot Feb 05 '16 at 07:51
  • It's through the server, don't worry about that. The way I intend to do it is User 1's thread acquires lock on User 0's `ObjectOutputStream` and sends what needs to be sent right away – Akash Agarwal Feb 05 '16 at 07:52
  • Let us [continue this discussion in chat](http://chat.stackoverflow.com/rooms/102668/discussion-between-gilad-mitrani-and-akash-aggarwal). – HazirBot Feb 05 '16 at 07:53