如题所述
synchronized(obj) {
while(!condition) {
obj.wait();
}
obj.doSomething();
}
当线程A获得了obj锁后,发现条件condition不满足,无法继续下一处理,于是线程A就wait() , 放弃对象锁.
之后在另一线程B中,如果B更改了某些条件,使得线程A的condition条件满足了,就可以唤醒线程A:
synchronized(obj) {
condition = true;
obj.notify();
}
需要注意的概念是:
# 调用obj的wait(), notify()方法前,必须获得obj锁,也就是必须写在synchronized(obj) {…} 代码段内。
# 调用obj.wait()后,线程A就释放了obj的锁,否则线程B无法获得obj锁,也就无法在synchronized(obj) {…} 代码段内唤醒A。
# 当obj.wait()方法返回后,线程A需要再次获得obj锁,才能继续执行。
# 如果A1,A2,A3都在obj.wait(),则B调用obj.notify()只能唤醒A1,A2,A3中的一个(具体哪一个由JVM决定)。
# obj.notifyAll()则能全部唤醒A1,A2,A3,但是要继续执行obj.wait()的下一条语句,必须获得obj锁,因此,A1,A2,A3只有一个有机会获得锁继续执行,例如A1,其余的需要等待A1释放obj锁之后才能继续执行。
# 当B调用obj.notify/notifyAll的时候,B正持有obj锁,因此,A1,A2,A3虽被唤醒,但是仍无法获得obj锁。直到B退出synchronized块,释放obj锁后,A1,A2,A3中的一个才有机会获得锁继续执行
while(!condition) {
obj.wait();
}
obj.doSomething();
}
当线程A获得了obj锁后,发现条件condition不满足,无法继续下一处理,于是线程A就wait() , 放弃对象锁.
之后在另一线程B中,如果B更改了某些条件,使得线程A的condition条件满足了,就可以唤醒线程A:
synchronized(obj) {
condition = true;
obj.notify();
}
需要注意的概念是:
# 调用obj的wait(), notify()方法前,必须获得obj锁,也就是必须写在synchronized(obj) {…} 代码段内。
# 调用obj.wait()后,线程A就释放了obj的锁,否则线程B无法获得obj锁,也就无法在synchronized(obj) {…} 代码段内唤醒A。
# 当obj.wait()方法返回后,线程A需要再次获得obj锁,才能继续执行。
# 如果A1,A2,A3都在obj.wait(),则B调用obj.notify()只能唤醒A1,A2,A3中的一个(具体哪一个由JVM决定)。
# obj.notifyAll()则能全部唤醒A1,A2,A3,但是要继续执行obj.wait()的下一条语句,必须获得obj锁,因此,A1,A2,A3只有一个有机会获得锁继续执行,例如A1,其余的需要等待A1释放obj锁之后才能继续执行。
# 当B调用obj.notify/notifyAll的时候,B正持有obj锁,因此,A1,A2,A3虽被唤醒,但是仍无法获得obj锁。直到B退出synchronized块,释放obj锁后,A1,A2,A3中的一个才有机会获得锁继续执行
温馨提示:答案为网友推荐,仅供参考
第1个回答 2015-01-24
不知道你正在试图做。 您可以使用下面,以供参考。
如果你实现Thread or HandlerThread ,确保您的UI线程不会阻塞而等待工作线程完成不致电Thread.wait()或Thread.sleep()
检查developer.android.com/training/articles/perf-anr.html
你不应该阻止你的主UI线程。 而不是一个定时器,你可以使用一个'处理器'
您可以启动和停止定时器按钮点击。 您可以重新安排您的定时器计数值。 你需要照顾的方向变化的活动被销毁并重新创建。 count的值,我们将重新初始化。
MainActivity.java
public class MainActivity extends Activity implements OnClickListener{
Timer t;
int count = 0;
boolean isDone = true;
Button b;
TextView tv;
Thread thread;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
b = (Button) findViewById(R.id.button1);
tv = (TextView) findViewById(R.id.textView1);
t = new Timer();
t.scheduleAtFixedRate(new TimerTask() {
@Override
public void run() {
// TODO Auto-generated method stub
runOnUiThread(new Runnable() {
public void run() {
tv.setText(String.valueOf(count));
if(isDone)
count++;
}
});
}
}, 1000, 1000);
b.setOnClickListener(this);
}
@Override
public void onClick(View v) {
// TODO Auto-generated method stu
final Dialog d = new Dialog(MainActivity.this);
d.setTitle("Pause Menu");
d.setContentView(R.layout.pausemenu);
Button b1 = (Button) d.findViewById(R.id.button1);
Button b2 = (Button) d.findViewById(R.id.button2);
b1.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
// TODO Auto-generated method stub
t.cancel();
d.dismiss();
}
});
b2.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
// TODO Auto-generated method stub
if(isDone)
{
t.cancel();
isDone=false;
}
t = new Timer();
t.scheduleAtFixedRate(new TimerTask() {
@Override
public void run() {
// TODO Auto-generated method stub
runOnUiThread(new Runnable() {
public void run() {
tv.setText(String.valueOf(count));
count++;
}
});
}
}, 1000, 1000);
d.dismiss();
}
});
d.show();
}
}
main.xml
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android=""
android:layout_width="match_parent"
android:layout_height="match_parent" >
<TextView
android:id="@+id/textView1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerHorizontal="true"
android:layout_centerVertical="true"
android:textSize="20sp"
android:text="TextView" />
<Button
android:id="@+id/button1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentBottom="true"
android:layout_alignRight="@+id/textView1"
android:layout_marginBottom="21dp"
android:text="Button" />
</RelativeLayout>
pausemenu.xml
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android=""
android:layout_width="match_parent"
android:layout_height="match_parent" >
<Button
android:id="@+id/button1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentBottom="true"
android:layout_alignParentLeft="true"
android:layout_marginBottom="118dp"
android:layout_marginLeft="51dp"
android:text="Stop" />
<Button
android:id="@+id/button2"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignBaseline="@+id/button1"
android:layout_alignBottom="@+id/button1"
android:layout_marginLeft="32dp"
android:layout_toRightOf="@+id/button1"
android:text="Start" />
</RelativeLayout>
编辑:
使用处理程序
Handler m_handler;
Runnable m_handlerTask ;
m_handlerTask = new Runnable()
{
@Override
public void run() {
if(isDone)
{
tv.setText(""+count);
count++;
m_handler.postDelayed(m_handlerTask, 1000);
}
// m_handler.removeCallbacks(m_handlerTask);
}
};
m_handlerTask.run();
你应该停止定时器和处理程序时,不需要取消。
如果你t.cancel()使用定时器和使用m_handler.removeCallbacks(m_handlerTask)停止处理程序呼叫
如果你实现Thread or HandlerThread ,确保您的UI线程不会阻塞而等待工作线程完成不致电Thread.wait()或Thread.sleep()
检查developer.android.com/training/articles/perf-anr.html
你不应该阻止你的主UI线程。 而不是一个定时器,你可以使用一个'处理器'
您可以启动和停止定时器按钮点击。 您可以重新安排您的定时器计数值。 你需要照顾的方向变化的活动被销毁并重新创建。 count的值,我们将重新初始化。
MainActivity.java
public class MainActivity extends Activity implements OnClickListener{
Timer t;
int count = 0;
boolean isDone = true;
Button b;
TextView tv;
Thread thread;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
b = (Button) findViewById(R.id.button1);
tv = (TextView) findViewById(R.id.textView1);
t = new Timer();
t.scheduleAtFixedRate(new TimerTask() {
@Override
public void run() {
// TODO Auto-generated method stub
runOnUiThread(new Runnable() {
public void run() {
tv.setText(String.valueOf(count));
if(isDone)
count++;
}
});
}
}, 1000, 1000);
b.setOnClickListener(this);
}
@Override
public void onClick(View v) {
// TODO Auto-generated method stu
final Dialog d = new Dialog(MainActivity.this);
d.setTitle("Pause Menu");
d.setContentView(R.layout.pausemenu);
Button b1 = (Button) d.findViewById(R.id.button1);
Button b2 = (Button) d.findViewById(R.id.button2);
b1.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
// TODO Auto-generated method stub
t.cancel();
d.dismiss();
}
});
b2.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
// TODO Auto-generated method stub
if(isDone)
{
t.cancel();
isDone=false;
}
t = new Timer();
t.scheduleAtFixedRate(new TimerTask() {
@Override
public void run() {
// TODO Auto-generated method stub
runOnUiThread(new Runnable() {
public void run() {
tv.setText(String.valueOf(count));
count++;
}
});
}
}, 1000, 1000);
d.dismiss();
}
});
d.show();
}
}
main.xml
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android=""
android:layout_width="match_parent"
android:layout_height="match_parent" >
<TextView
android:id="@+id/textView1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerHorizontal="true"
android:layout_centerVertical="true"
android:textSize="20sp"
android:text="TextView" />
<Button
android:id="@+id/button1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentBottom="true"
android:layout_alignRight="@+id/textView1"
android:layout_marginBottom="21dp"
android:text="Button" />
</RelativeLayout>
pausemenu.xml
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android=""
android:layout_width="match_parent"
android:layout_height="match_parent" >
<Button
android:id="@+id/button1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentBottom="true"
android:layout_alignParentLeft="true"
android:layout_marginBottom="118dp"
android:layout_marginLeft="51dp"
android:text="Stop" />
<Button
android:id="@+id/button2"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignBaseline="@+id/button1"
android:layout_alignBottom="@+id/button1"
android:layout_marginLeft="32dp"
android:layout_toRightOf="@+id/button1"
android:text="Start" />
</RelativeLayout>
编辑:
使用处理程序
Handler m_handler;
Runnable m_handlerTask ;
m_handlerTask = new Runnable()
{
@Override
public void run() {
if(isDone)
{
tv.setText(""+count);
count++;
m_handler.postDelayed(m_handlerTask, 1000);
}
// m_handler.removeCallbacks(m_handlerTask);
}
};
m_handlerTask.run();
你应该停止定时器和处理程序时,不需要取消。
如果你t.cancel()使用定时器和使用m_handler.removeCallbacks(m_handlerTask)停止处理程序呼叫