何时使用volatile和synchronized [英] When to use volatile and synchronized

查看:135
本文介绍了何时使用volatile和synchronized的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我知道有很多问题,但我仍然不太明白。我知道这两个关键字的作用,但我无法确定在某些情况下使用哪个。以下是我要确定最好使用的几个示例。

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.

示例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();
    }

}

示例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;
    }

}

非常感谢任何帮助。

推荐答案

挥发性关键字:

如果您正在使用多线程编程,volatile关键字将更有用。当多个线程使用相同的变量时,每个线程将拥有自己的该变量的本地缓存副本。

If you are working with multi-threaded programming, the volatile keyword will be more useful. When multiple threads using the same variable, each thread will have its own copy of the local cache for that variable.

因此,当它更新值时,它实际上在本地缓存中更新而不是在主变量内存中。使用相同变量的另一个线程对另一个线程更改的值一无所知。

So, when it’s updating the value, it is actually updated in the local cache not in the main variable memory. The other thread which is using the same variable doesn’t know anything about the values changed by the another thread.

为避免此问题,如果将变量声明为volatile,则不会将其存储在本地缓存中。每当线程更新值时,它都会更新到主存储器。因此,其他线程可以访问更新的值。

To avoid this problem, if you declare a variable as volatile, then it will not be stored in the local cache. Whenever thread are updating the values, it is updated to the main memory. So, other threads can access the updated value.

挥发性示例:

class ExampleThread extends Thread {
    private volatile int testValue;
    public ExampleThread(String str){
        super(str);
    }
    public void run() {
        for (int i = 0; i < 3; i++) {
            try {
                System.out.println(getName() + " : "+i);
                if (getName().equals("Thread 1"))
                {
                    testValue = 10;
                }
                if (getName().equals("Thread 2"))
                {
                    System.out.println( "Test Value : " + testValue);
                }               
                Thread.sleep(1000);
            } catch (InterruptedException exception) {
                exception.printStackTrace();
            }
        }
    }
}
public class VolatileExample {
    public static void main(String args[]) {
        new ExampleThread("Thread 1").start();
        new ExampleThread("Thread 2").start();
    }
}

同步关键字:

synchronized关键字可以应用于语句块或方法。 synchronized关键字为关键部分提供保护,这些部分一次只能由单个线程执行。 synchronized关键字避免了关键代码一次被多个线程执行。

The synchronized keyword may be applied to a statement block or to a method. The synchronized keyword provides the protection for the crucial sections that are required only to be executed by a single thread once at a time. The synchronized keyword avoids a critical code from being executed by more than one thread at a time.

它限制其他线程同时访问资源。如果将synchronized关键字应用于静态方法,我们将通过下面的示例使用具有SyncStaticMethod方法的类来显示它,则整个类在执行和控制一个线程的方法时被锁定。

It restricts other threads to concurrently access a resource. If the synchronized keyword is applied to a static method, as we will show it with a class having a method SyncStaticMethod through an example below, the entire class get locked while the method under execution and control of a one thread at a time.

当synchronized关键字应用于实例方法时,正如我们在下面给出的示例中使用SyncMethod一样,实例在被访问时被锁定,并且在执行和控制下一次一个线程。

When the synchronized keyword is applied to an instance method, as we have done with SyncMethod in the example given below, the instance get locked while being accessed and under execution and control of a one thread at a time.

当synchronized关键字应用于某个对象时,该对象会被锁定,尽管与之关联的代码块会被一个线程执行。

When the synchronized keyword is applied to an object, then that object is locked though the code block associated with it get executed by one thread at at time.

同步示例:

public class Class1{
   public synchronized static String SyncStaticMethod(){

   }
   public synchronized String SyncMethod(){

   }
{

public class Class2{
     Object Obj;
     public String Method2(){
          <statements>
          synchronized (Obj){
             <statements affecting Obj>
          }
     }
}

这篇关于何时使用volatile和synchronized的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆