【问题标题】:Does aliasing make any difference on thread safety?别名对线程安全有什么影响吗?
【发布时间】:2020-09-04 16:51:45
【问题描述】:

下面的代码首先通过向下转换来访问变量,我想知道如果方法的返回类型返回与我正在使用的别名相同的别名(ContainerPieceVolumesBinding binding)是否有什么不同,或者作为方法参数传入的那个。

我已经测试了代码,它似乎运行良好,问题是同一变量可能有第二个访问点(第二个访问点是可选的)。

理论上,第二个访问点将使用 viewBind 别名,而不是我正在使用的降级版本。

如果我不返回方法参数抛出的相同别名,而是返回向下转换的版本,会有什么不同,会更安全吗?

@SuppressWarnings("unchecked")
@Override
public ViewDataBinding setData(ViewDataBinding viewBind, @NonNull String bindingTag) {
    
    BindingVisitorsBaseAdapter adapter = new BindingVisitorsBaseAdapter(
            TAG
    );
    adapter.setCompletePendingBindings(
            pendingBindings
    );
    //This is the downcasted alias
    ContainerPieceVolumesBinding binding = (ContainerPieceVolumesBinding) viewBind;
    binding.pieceVolumesContainer.setAdapter(adapter);
    observer = new ObjectNotifier(
    ) {
        @Override
        public Notifier onNotified() {
            return (response, responseType) -> {
                switch (responseType) {
                    case SUBMIT_LIST :
                        List<BindingVisitor> pieceVolumes = (List<BindingVisitor>) response[0];
                        ((BindingVisitorsBaseAdapter)binding.pieceVolumesContainer.getAdapter()).submitList(pieceVolumes);
                        break;
                    case QUANTITY_CHANGE:
                        onQuantityChanged.onChanged(getValues(binding.pieceVolumesContainer));
                        break;
                }
            };
        }
    };
    observer.notifyResponse(SUBMIT_LIST, new ArrayList<>());
   // returning the original version here
    return viewBind;
}

【问题讨论】:

  • 除非您通过对象调用引用静态方法,否则向上转换和向下转换不会影响调用的安全性
  • 由于您将其标记为“指针”并且基于问题听起来您假设与 C / C++ 类似的行为 MyClass copied = original 实际上创建了一个副本。但是,在 Java 中并非如此。在 Java 中,您正在使用引用(您可以将其想象为指针),因此 @ControlAltDel 编写的强制转换无效,两个变量仍然引用同一个对象实例。另请注意,测试某事物是否是线程安全的(很容易)是不可能的,因为线程安全问题可能很少见,而且通常无法始终如一地重现。
  • @Marcono1234 它确实对静态方法调用有影响

标签: java pointers reference thread-safety alias


【解决方案1】:

除非您通过对象调用引用静态方法,否则向上转换和向下转换不会影响调用的安全性

public class A {
  public void foo() {
    System.out.println("A");
  }
  public static void bar() {
    System.out.println("As"); 
  }
}

public class B extends A {
  private void foo() {
    System.out.println("B");
  }
  public static void bar() {
    System.out.println("Bs"); 
  }
}

A var = new B();

var.foo(); //will print B
var.bar(); //will print A

((B)var).foo(); //will print B 
((B)var).bar(); //will print B

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2011-08-06
    • 2018-09-13
    • 2019-03-13
    • 1970-01-01
    • 2014-10-05
    • 1970-01-01
    • 2019-03-12
    • 1970-01-01
    相关资源
    最近更新 更多