Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/multithreading/4.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_Concurrency_Coding Style - Fatal编程技术网

在java中,将本地对象传递给线程的方式是错误的吗?

在java中,将本地对象传递给线程的方式是错误的吗?,java,multithreading,concurrency,coding-style,Java,Multithreading,Concurrency,Coding Style,我发现我经常做下面的事情。制作要发送到线程的对象的副本。线程是唯一一个使用该对象的线程,我们有一个before-before关系,因此它是线程安全的 但这让我感到紧张。如评论所述,如果有人出现并使用objForThread进行欺骗,该怎么办? 我应该用锁吗?或者这是一种普遍接受的java模式 class Example { private SomeObj mDynamicObj = new SomeObj(); public void doWorkInAThread() {

我发现我经常做下面的事情。制作要发送到线程的对象的副本。线程是唯一一个使用该对象的线程,我们有一个before-before关系,因此它是线程安全的

但这让我感到紧张。如评论所述,如果有人出现并使用objForThread进行欺骗,该怎么办? 我应该用锁吗?或者这是一种普遍接受的java模式

class Example
{
  private SomeObj mDynamicObj = new SomeObj();

  public void doWorkInAThread()
  {
    mutateThis(mDynamicObj);
    final SomeObj objForThread = new SomeObj(mDynamicObj);

    myExecutorService.submit(new Runnable() { @Override public void run()
    {
      doSomethingWith(objForThread);
    }});

    mutateThis(mDynamicObj);

    // Concerned that in the future someone will come
    // along and mutate objForThread here making this thread unsafe
  }
}

这完全取决于你想要达到的目标。 一些数据被设计成由多个线程访问和修改。 某些数据仅设计用于线程安全环境

如果你需要更详细的解释,你必须提供一个真实的例子

此外,有些类被设计为线程安全的或不可变的。例如,共享字符串或整数是非常好的。但是,对这些对象的实际引用可能会更改,因此如果依赖于此类引用,则可能会出现问题

在您的示例中,后一种情况并非如此,因为您通过final变量引用对象。但是,如果要引用成员变量mDynamicObject,那么如果另一个线程中有人为其分配了不同的对象(mDynamicObject=new SomeObj()),则会出现问题。如果没有适当的同步,它可能会导致应用程序处于奇怪的状态。为了避免这种情况,您可以将其指定给最终变量并引用

考虑将尽可能多的参数传递给新线程调用,而不是引用它们。这将保证引用的内容不会更改


当然,如果需要,对象本身最好是不可变的或正确同步的。

这完全取决于您试图实现的目标。 一些数据被设计成由多个线程访问和修改。 某些数据仅设计用于线程安全环境

如果你需要更详细的解释,你必须提供一个真实的例子

此外,有些类被设计为线程安全的或不可变的。例如,共享字符串或整数是非常好的。但是,对这些对象的实际引用可能会更改,因此如果依赖于此类引用,则可能会出现问题

在您的示例中,后一种情况并非如此,因为您通过final变量引用对象。但是,如果要引用成员变量mDynamicObject,那么如果另一个线程中有人为其分配了不同的对象(mDynamicObject=new SomeObj()),则会出现问题。如果没有适当的同步,它可能会导致应用程序处于奇怪的状态。为了避免这种情况,您可以将其指定给最终变量并引用

考虑将尽可能多的参数传递给新线程调用,而不是引用它们。这将保证引用的内容不会更改


当然,如果需要,对象本身最好是不可变的或正确同步的。

如果您感到紧张,最好将引用传递给线程,而不是将其保持在本地:

class Example
{
    private SomeObj mDynamicObj = new SomeObj ();

    public void doWorkInAThread ()
    {
        class MyRunnable implements Runnable
        {
            private final SomeObj objForThread;

            public MyRunnable (SomeObj objForThread)
            {
                this.objForThread = objForThread;
            }

            @Override
            public void run ()
            {
                doSomethingWith (objForThread);
            }
        }

        mutateThis (mDynamicObj);

        myExecutorService.submit (new MyRunnable (new SomeObj (mDynamicObj)));

        mutateThis (mDynamicObj);
    }
}

如果您感到紧张,最好将引用传递给线程,而不要将其保留在本地:

class Example
{
    private SomeObj mDynamicObj = new SomeObj ();

    public void doWorkInAThread ()
    {
        class MyRunnable implements Runnable
        {
            private final SomeObj objForThread;

            public MyRunnable (SomeObj objForThread)
            {
                this.objForThread = objForThread;
            }

            @Override
            public void run ()
            {
                doSomethingWith (objForThread);
            }
        }

        mutateThis (mDynamicObj);

        myExecutorService.submit (new MyRunnable (new SomeObj (mDynamicObj)));

        mutateThis (mDynamicObj);
    }
}

保护代码不受可能破坏代码的更改的影响是很困难的

你可以说这不是你的问题。您可以添加警告注释并继续。或者你可以假设下一个家伙足够聪明/谨慎,能够理解他的变化的含义

或者你可以采取防御措施,比如将SomeObj更改为线程安全的,甚至是不可变的。。。即使这可能会增加额外的运行时开销

哪种方法最好?我想我不能就此提出建议。取决于更高层次的问题;e、 g.团队及其代码审查和测试过程有多好,整个应用程序有多复杂,性能有多关键,错误有多关键,等等



对于这个特定的“示例”,您已经抽象出了任何类似于应用程序逻辑的东西,这使得您很难知道哪种方法是最好的。传递本地对象是“好”还是“坏”取决于上下文。

保护代码不受可能破坏它的更改的影响是很困难的

你可以说这不是你的问题。您可以添加警告注释并继续。或者你可以假设下一个家伙足够聪明/谨慎,能够理解他的变化的含义

或者你可以采取防御措施,比如将SomeObj更改为线程安全的,甚至是不可变的。。。即使这可能会增加额外的运行时开销

哪种方法最好?我想我不能就此提出建议。取决于更高层次的问题;e、 g.团队及其代码审查和测试过程有多好,整个应用程序有多复杂,性能有多关键,错误有多关键,等等



对于这个特定的“示例”,您已经抽象出了任何类似于应用程序逻辑的东西,这使得您很难知道哪种方法是最好的。传递本地对象是“好”还是“坏”取决于上下文。

我看不出这有什么错。可以从中访问
objForThread
的范围非常小。如果
objForThread
是线程安全的,或者更常见的情况是不可变的,那就好了。@millimoose:的确如此。如果需要的话,可以通过使用一个裸块
{…}
使它变得更小。如果有人来做一些不应该做的事情,就会有bug。不管你在写什么代码,这都是事实。考虑复制一个不可变的副本,或者记录一个事实,即拷贝不能被突变。但是代码是安全的。不,你需要一个内部类来添加构造函数args@millimoose。我看不出这有什么错。可以从中访问
objForThread
的范围非常小。如果
objForThread
是线程安全的,或者更常见的情况是不可变的,那就好了。@millimoose:的确如此。而且它可以变得更小,如果