Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/batch-file/5.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 是否可以将非同步方法称为已同步?_Java_Multithreading_Runnable_Synchronized - Fatal编程技术网

Java 是否可以将非同步方法称为已同步?

Java 是否可以将非同步方法称为已同步?,java,multithreading,runnable,synchronized,Java,Multithreading,Runnable,Synchronized,我有一个类ClassA,它有一个public void doSomething()方法。该ClassA广泛用于不同的应用;有些需要同步,有些则不需要。同样的情况是,当我不需要时,我不希望调用synchronized方法带来(微小但非零)的性能影响 假设ClassB将调用doSomething()并要求这是synchronized,而ClassC不要求这一点。在我的程序设计中,我可以通过哪些方式实现这一点 在ClassB中使用该方法是否足够: private synchronized void d

我有一个类
ClassA
,它有一个
public void doSomething()
方法。该
ClassA
广泛用于不同的应用;有些需要
同步
,有些则不需要。同样的情况是,当我不需要时,我不希望调用
synchronized
方法带来(微小但非零)的性能影响

假设
ClassB
将调用
doSomething()
并要求这是
synchronized
,而
ClassC
不要求这一点。在我的程序设计中,我可以通过哪些方式实现这一点

ClassB
中使用该方法是否足够:

private synchronized void doSomething() {
    this.classAInstance.doSomething();
}

因此,避免了将
ClassC
doSomething()
指定为
synchronized

当您需要使用同一个类进行同步和不进行同步时,一种常见的方法是创建一个接口,并提供两种实现—一个非同步类和实际实现,和一个添加同步的薄包装器

下面是一个简单的例子:假设您正在构建一个包含两个操作的类-
getSomething
setSomething
。界面可能如下所示:

interface Demo {
    void setSomething(Something value);
    Something getSomething();
}
class DemoImpl implements Demo {
    private Something theSomething;
    public void setSomething(Something value) {
        theSomething = value;
    }
    public Something getSomething() {
        return theSomething;
    }
}
现在,非同步实现可能如下所示:

interface Demo {
    void setSomething(Something value);
    Something getSomething();
}
class DemoImpl implements Demo {
    private Something theSomething;
    public void setSomething(Something value) {
        theSomething = value;
    }
    public Something getSomething() {
        return theSomething;
    }
}
最后,同步实现:

class SyncDemoImpl implements Demo {
    private DemoImpl impl = new DemoImpl();
    public synchronized void setSomething(Something value) {
        impl.setSomething(value);
    }
    public synchronized Something getSomething() {
        return impl.getSomething();
    }
}

当您需要在同步和不同步的情况下使用同一个类时,一种常见的方法是创建一个接口,并提供两个实现—一个包含实际实现的非同步类和一个添加同步的瘦包装器

下面是一个简单的例子:假设您正在构建一个包含两个操作的类-
getSomething
setSomething
。界面可能如下所示:

interface Demo {
    void setSomething(Something value);
    Something getSomething();
}
class DemoImpl implements Demo {
    private Something theSomething;
    public void setSomething(Something value) {
        theSomething = value;
    }
    public Something getSomething() {
        return theSomething;
    }
}
现在,非同步实现可能如下所示:

interface Demo {
    void setSomething(Something value);
    Something getSomething();
}
class DemoImpl implements Demo {
    private Something theSomething;
    public void setSomething(Something value) {
        theSomething = value;
    }
    public Something getSomething() {
        return theSomething;
    }
}
最后,同步实现:

class SyncDemoImpl implements Demo {
    private DemoImpl impl = new DemoImpl();
    public synchronized void setSomething(Something value) {
        impl.setSomething(value);
    }
    public synchronized Something getSomething() {
        return impl.getSomething();
    }
}

请记住,这纯粹是一项学术活动。我看不出资源需要选择性同步访问的任何实际原因。要么你需要,要么你不需要。如果你必须这样做,你将在接下来的几个月里为自己设置长时间的故障排除。如果可以,我会重新考虑设计

所以, 您会说-'有些需要同步,有些则不需要'

我认为这意味着您确切地知道需要同步访问的代码的每一部分,并且可以将其与需要节省此开销的代码区分开来。如果是:您有两个选择:

  • 同时去掉方法的synchronized修饰符,让所有需要同步的调用方在调用之前进行同步。因此:

    synchronized (classAInstance){
        classAInstance.doSomething();  // the doSomething() is non-synchronised
    }
    
  • 代码中调用此方法且不需要同步访问的部分可以直接调用此方法

  • 创建两个方法,一个是同步的,另一个是不同步的。根据您希望控制访问的方式将呼叫者更改为呼叫

  • 请记住,这纯粹是一项学术活动。我看不出资源需要选择性同步访问的任何实际原因。要么你需要,要么你不需要。如果你必须这样做,你将在接下来的几个月里为自己设置长时间的故障排除。如果可以,我会重新考虑设计

    所以, 您会说-'有些需要同步,有些则不需要'

    我认为这意味着您确切地知道需要同步访问的代码的每一部分,并且可以将其与需要节省此开销的代码区分开来。如果是:您有两个选择:

  • 同时去掉方法的synchronized修饰符,让所有需要同步的调用方在调用之前进行同步。因此:

    synchronized (classAInstance){
        classAInstance.doSomething();  // the doSomething() is non-synchronised
    }
    
  • 代码中调用此方法且不需要同步访问的部分可以直接调用此方法

  • 创建两个方法,一个是同步的,另一个是不同步的。根据您希望控制访问的方式将呼叫者更改为呼叫

  • 对于问题中的
    synchronized
    做了什么,基本上缺乏理解。要么你需要货币安全,要么你不需要,有时没有……因为你有时需要。@user2763361我可以想出一个这样的用例,但我真的想问你是否可以,因为我真的怀疑你是否需要从这个设计开始。@JarrodRoberson等人-OP说他在多个不同的项目中使用同一个类。其中一些项目是针对多线程应用程序的,有些则不是;因此,他在某些时候只需要一个同步对象。@user2763361:除非你已经证明这是一个实际的问题,否则你只是在试图解决一个不存在的问题。对于
    synchronized
    在问题中的作用,基本上缺乏理解。要么你需要货币安全,要么你不需要,有时没有……因为你有时需要。@user2763361我可以想出一个这样的用例,但我真的想问你是否可以,因为我真的怀疑你是否需要从这个设计开始。@JarrodRoberson等人-OP说他在多个不同的项目中使用同一个类。其中一些项目是针对多线程应用程序的,有些则不是;因此,他在某些时候只需要一个同步对象。@user2763361:除非你已经证明这是一个实际问题,否则你只是想解决一个不存在的问题。或者更一般地说,线程安全实现和非线程安全实现,根据所使用的模式可能会有很大的不同。或者更一般地说,线程安全实现和非线程安全实现,根据使用的模式可能会有很大不同。