sleep和wait区别
- sleep是线程Thread的方法,wait是Object的方法
- 都有使该线程暂时休眠的效果,但是Thread.sleep不会释放出该锁的资源,但是会让出CPU的资源,object.wait可是释放该线程的资源
- Thread.sleep在任何情况下都能执行,object.wait必须在syncnized代码块中执行
案例:
start按钮启动线程1,一直循环工作打印
当点击wait按钮时,停止线程1的循环工作,wait标志为true
当点击notify按钮时,唤醒线程1,使得线程1继续工作打印
public class ThreadWaitActivity extends AppCompatActivity {
@BindView(R.id.wait)
Button mWait;
@BindView(R.id.notify)
Button mNotify;
@BindView(R.id.start)
Button mStart;
private Object mObject;
private boolean wait = false;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_thread_wait);
ButterKnife.bind(this);
mObject = new Object();
}
@OnClick(R.id.wait)
public void onWaitClicked() {
wait = true;
}
@OnClick(R.id.notify)
public void onNotifyClicked() {
Thread thread = new Thread(new Runnable() {
@Override
public void run() {
Logger.i("thread work :" + Thread.currentThread().getName());
synchronized (mObject) {
wait = false;
//调用后虚拟机可选择任何一个调用了mObject.wait()的线程投入运行,选择顺序不由代码控制,由虚拟机实现。
//如果是notifyAll(),则唤醒所有等待的线程运行。
mObject.notify();
}
}
},"thread2");
thread.start();
}
@OnClick(R.id.start)
public void onClicked() {
Thread thread = new Thread(new Runnable() {
@Override
public void run() {
while (true) {
try {
Thread.sleep(2000);
} catch (InterruptedException e) {
e.printStackTrace();
}
Logger.i("wait :" + wait);
if (wait) {
try {
synchronized (mObject) {
//此处调用后该线程不再活动,置于等待状态,切换到其他线程运行
mObject.wait();
}
} catch (Exception e) {
e.printStackTrace();
}
}
Logger.i("thread work :" + Thread.currentThread().getName());
}
}
},"thread1");
thread.start();
}
}
join和yield
A线程和B线程在运行(这里面还有UI主线程暂时忽略)
- A.join()则会插队B线程,直到A线程执行完毕,才轮到B(阻塞状态)
- A.yield()释放CPU资源,使A从运行中转为可运行状态,然后A和B同时去竞争这个资源,所以当A.yield之后,下个执行的也有可能是A
案例
- 点击启动按钮,两个线程1,2运行
- 点击join按钮,线程1插入到main线程和2线程,直到1线程工作完毕,才轮到2线程
public class ThreadYieldActivity extends BaseActivity {
@BindView(R.id.start_thread1_btn)
Button mStartThread1Btn;
@BindView(R.id.yield)
Button mYield;
@BindView(R.id.join)
Button mJoin;
private Thread thread2;
private Thread thread1;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_thread_yield);
ButterKnife.bind(this);
}
@OnClick(R.id.start_thread1_btn)
public void onMStartThread1BtnClicked() {
thread1 = new Thread(new Runnable() {
@Override
public void run() {
for (int i = 0; i < 100; i++) {
Logger.i("-----------" + Thread.currentThread().getName());
}
}
}, "-------thread1");
thread2 = new Thread(new Runnable() {
@Override
public void run() {
for (int i = 0; i < 100; i++) {
Logger.i("-----------" + Thread.currentThread().getName());
}
}
}, "thread2");
thread2.setPriority(Thread.MAX_PRIORITY);
thread1.setPriority(Thread.MIN_PRIORITY);
thread2.start();
thread1.start();
}
@OnClick(R.id.yield)
public void onMYieldClicked() {
//线程1释放
thread1.yield();
}
@OnClick(R.id.join)
public void onMJoinClicked() {
try {
thread1.join();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}