Welcome to ShenZhenJia Knowledge Sharing Community for programmer and developer-Open, Learning and Share
menu search
person
Welcome To Ask or Share your Answers For Others

Categories

I know there are many questions about this, but I still don't quite understand. I know what both of these keywords do, but I can't determine which to use in certain scenarios. Here are a couple of examples that I'm trying to determine which is the best to use.

Example 1:

import java.net.ServerSocket;

public class Something extends Thread {

    private ServerSocket serverSocket;

    public void run() {
        while (true) {
            if (serverSocket.isClosed()) {
                ...
            } else { //Should this block use synchronized (serverSocket)?
                //Do stuff with serverSocket
            }
        }
    }

    public ServerSocket getServerSocket() {
        return serverSocket;
    }

}

public class SomethingElse {

    Something something = new Something();

    public void doSomething() {
        something.getServerSocket().close();
    }

}

Example 2:

public class Server {

    private int port;//Should it be volatile or the threads accessing it use synchronized (server)?

    //getPort() and setPort(int) are accessed from multiple threads
    public int getPort() {
        return port;
    }

    public void setPort(int port) {
        this.port = port;
    }

}

Any help is greatly appreciated.

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
thumb_up_alt 0 like thumb_down_alt 0 dislike
164 views
Welcome To Ask or Share your Answers For Others

1 Answer

A simple answer is as follows:

  • synchronized can always be used to give you a thread-safe / correct solution,

  • volatile will probably be faster, but can only be used to give you a thread-safe / correct in limited situations.

If in doubt, use synchronized. Correctness is more important than performance.

Characterizing the situations under which volatile can be used safely involves determining whether each update operation can be performed as a single atomic update to a single volatile variable. If the operation involves accessing other (non-final) state or updating more than one shared variable, it cannot be done safely with just volatile. You also need to remember that:

  • updates to non-volatile long or a double may not be atomic, and
  • Java operators like ++ and += are not atomic.

Terminology: an operation is "atomic" if the operation either happens entirely, or it does not happen at all. The term "indivisible" is a synonym.

When we talk about atomicity, we usually mean atomicity from the perspective of an outside observer; e.g. a different thread to the one that is performing the operation. For instance, ++ is not atomic from the perspective of another thread, because that thread may be able to observe state of the field being incremented in the middle of the operation. Indeed, if the field is a long or a double, it may even be possible to observe a state that is neither the initial state or the final state!


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
thumb_up_alt 0 like thumb_down_alt 0 dislike
Welcome to ShenZhenJia Knowledge Sharing Community for programmer and developer-Open, Learning and Share
...