Java Android:构造函数中的synchronized()无效?

Java Android:构造函数中的synchronized()无效?,java,android,constructor,synchronized,Java,Android,Constructor,Synchronized,我试着搜索这个问题,但没有找到任何东西,好像我是唯一一个尝试过的人 基本上,我有一个静态对象,用于在包含类的构造函数中同步资源访问,我不时注意到它不起作用 private static Integer lock = Integer.valueOf(0); public testClass(Context ctx) { if (ctx != null) context = ctx.getApplicationContext(); else

我试着搜索这个问题,但没有找到任何东西,好像我是唯一一个尝试过的人

基本上,我有一个静态对象,用于在包含类的构造函数中同步资源访问,我不时注意到它不起作用

private static Integer              lock = Integer.valueOf(0);

public testClass(Context ctx)
{
    if (ctx != null)
        context = ctx.getApplicationContext();
    else
        context = null;

    synchronized(lock)
    {
        Log.v(at_data.TAG, "I_AM_IN=" + I_AM_IN);
        I_AM_IN = true;

      // Access resource
      // 
      // Multiple threads do enter here!

        Log.v(at_data.TAG, "I_AM_OUT=" + I_AM_IN);
        I_AM_IN = false;
    }
}
我可能错过了一些东西,但没有找到任何文件说它不应该工作

输出:

I_AM_IN=false
I_AM_IN=true
I_AM_OUT=true
I_AM_OUT=false
但大多数情况下都是这样:

I_AM_IN=false
I_AM_OUT=true
I_AM_IN=false
I_AM_OUT=true

根据您的评论,问题在于您正在修改锁。不能增加整数对象的值。整数是不可变的,因此每次“递增”它时,都会用另一个锁替换该锁:

lock = new Integer(lock.intValue() + 1);
使用final
新对象()
作为锁,并使用单独的变量保存计数。或者使用原子整数。信号量也可能是您要查找的类


经验法则:锁应该始终是最终的。而且您永远不应该将共享对象用作锁(
Integer.valueOf(0)
是一个共享对象,因为至少在某些VM实现中,
valueOf(0)
总是返回相同的整数实例)。

根据您的评论,问题在于您正在修改锁。不能增加整数对象的值。整数是不可变的,因此每次“递增”它时,都会用另一个锁替换该锁:

lock = new Integer(lock.intValue() + 1);
使用final
新对象()
作为锁,并使用单独的变量保存计数。或者使用原子整数。信号量也可能是您要查找的类


经验法则:锁应该始终是最终的。而且您永远不应该使用共享对象作为锁(
Integer.valueOf(0)
是一个共享对象,因为至少在某些VM实现中,
valueOf(0)
总是返回相同的整数实例)。

您确定多个线程同时在同步块内吗?哦,是的。编辑同步块并添加输出。这快把我逼疯了!我只能认为,
lock
正在改变。如果您将其设置为
final
,您可能会发现在哪里。您可以发布一个完整的示例吗?此外,Integer.valueOf(0)不应用作锁。它(可能)是一个共享对象,如果其他类像您这样做,您将同步不相关的块,从而导致缓慢(在好的情况下)或死锁(在坏的情况下)。只需使用
newobject()
即可。您确定多个线程同时位于同步块内吗?哦,是的。编辑同步块并添加输出。这快把我逼疯了!我只能认为,
lock
正在改变。如果您将其设置为
final
,您可能会发现在哪里。您可以发布一个完整的示例吗?此外,Integer.valueOf(0)不应用作锁。它(可能)是一个共享对象,如果其他类像您这样做,您将同步不相关的块,从而导致缓慢(在好的情况下)或死锁(在坏的情况下)。只需使用
newobject()
即可。为什么会有帮助?我目前使用该锁作为计数器,以了解何时不再存在此类的对象,因此无法真正使用final。无论如何,我都会尝试使用一个备用对象进行计数,看看这是否有帮助。Nizet给出了一个更完整的答案。此外,显式锁定自己是非常棘手的,正如您所看到的,很容易出错。你应该调查遗嘱执行人。为什么会有帮助?我目前使用该锁作为计数器,以了解何时不再存在此类的对象,因此无法真正使用final。无论如何,我都会尝试使用一个备用对象进行计数,看看这是否有帮助。Nizet给出了一个更完整的答案。此外,显式锁定自己是非常棘手的,正如您所看到的,很容易出错。你应该调查遗嘱执行人。感谢最后的提示,正是出于这个原因,LINT建议使用Integer.valueOf,我做了一个全局替换;)顺便说一句,作为一名C#dev,我成功地使用Integer作为锁,因为该语言/框架提供了一种incrementlock类型的方法(据我所知)。C#还允许重写++运算符,该运算符(未验证)应使Integer类实际上是可变的,因为引用/指针保持不变,但内部数据被修改。这就是我对这行的期望:lock++;感谢最后的提示,正是出于这个原因,LINT建议使用Integer.valueOf,我做了一个全局替换;)顺便说一句,作为一名C#dev,我成功地使用Integer作为锁,因为该语言/框架提供了一种incrementlock类型的方法(据我所知)。C#还允许重写++运算符,该运算符(未验证)应使Integer类实际上是可变的,因为引用/指针保持不变,但内部数据被修改。这就是我对这行的期望:lock++;