我有这个简单的线程:
aQueueThread = new Thread(new Runnable()
{
@Override
public void run()
{
try
{
while(!Thread.interrupted())
{
QueueElementWrapper wrapper = aRequestsQueue.take();
Thread.sleep(2000);
synchronized(aQueueLock)
{
// Thread.sleep(2000);
aMainExecutor.submit(wrapper.aCallable);
if(wrapper.aRequestType == EQueueElementType.RELOGIN)
aQueueLock.wait();
}
}
}
catch(InterruptedException ie)
{
}
finally
{
}
}
}, "DownloaderThread");
aQueueThread.setDaemon(true);
aQueueThread.start();
运行循环中有一个LinkedBlockingDeque(即aRequestsQueue引用)。
现在,我在MainThread中运行另一个方法,该方法也使用基于aQueueLock的synchronized块。当我在synchronized块之外使用Thread.sleep()方法时,一切都很好。一旦这个方法离开它的同步blo,MainThread就会启动但是,如果我将它移动2行,那么它将在sychronized块内,由于某种原因,MainThread正在等待,直到aRequestsQueue内部没有更多元素,直到它被允许输入其他方法同步块。
任何人都可以为我解开这个谜团吗?
//修改
好的,为了排除我复杂代码中的原因,我快速地写了一个测试代码。使用单个Activity创建了一个空的android项目。我在主要布局中添加了一个白色的200x200视图:
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:paddingBottom="@dimen/activity_vertical_margin"
android:paddingLeft="@dimen/activity_horizontal_margin"
android:paddingRight="@dimen/activity_horizontal_margin"
android:paddingTop="@dimen/activity_vertical_margin"
tools:context=".MainActivity" >
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/hello_world" />
<View
android:id="@+id/view"
android:layout_width="200dip"
android:layout_height="200dip"
android:background="@android:color/white"
android:visibility="invisible"
/>
</RelativeLayout>
修改了MainActivity以更改此视图的可见性,如下所示:
public class MainActivity extends Activity
{
Object lockObject = new Object();
@Override
protected void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Thread thread = new Thread(new Runnable()
{
@Override
public void run()
{
try
{
for(int i = 0 ; i < 5 ; i++)
{
// Thread.sleep(2000);
synchronized(lockObject)
{
Thread.sleep(2000);
}
}
}
catch (InterruptedException e1)
{
// TODO Auto-generated catch block
e1.printStackTrace();
}
}
});
thread.setDaemon(true);
thread.start();
new CountDownTimer(4000, 4000)
{
@Override
public void onTick(long millisUntilFinished)
{
}
@Override
public void onFinish()
{
synchronized(lockObject)
{
findViewById(R.id.view).setVisibility(View.VISIBLE);
}
}
}.start();
}
@Override
public boolean onCreateOptionsMenu(Menu menu)
{
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.main, menu);
return true;
}
}
我认为它不会比这更简单。如果将sleep()调用保留在synchronized块内,则在10秒后出现白色方块。如果您评论那个,并将其留在同步块之外,您将在4秒后看到白色方块。