2,图示
以前的锁:三个方法能操作线程池中的所有线程,但只有一组监听器。
现在的锁:三个方法分别操作两个监听器中的对象。
14-8,JDK1.5解决方法―范例
这是JDK API文档中Condition接口中给出的范例:
class BoundedBuffer {
final Lock lock = new ReentrantLock();
final Condition notFull = lock.newCondition();
final Condition notEmpty = lock.newCondition();
final Object[] items = new Object[100];
int putptr, takeptr, count;
public void put(Object x) throws InterruptedException {
lock.lock();
try {
while (count == items.length)
notFull.await();
items[putptr] = x;
if (++putptr == items.length) putptr = 0;
++count;
notEmpty.signal();
} finally {
lock.unlock();
}
}
public Object take() throws InterruptedException {
lock.lock();
try {
while (count == 0)
notEmpty.await();
Object x = items[takeptr];
if (++takeptr == items.length) takeptr = 0;
--count;
notFull.signal();
return x;
} finally {
lock.unlock();
}
}
}
14-9,多线程-wait和sleep的区别
1,wait和sleep的区别?
(1)wait可以指定时间也可以不指定。
sleep必须执行时间。
(2)在同步中时,对CPU的执行权和锁的处理不同。
wait:释放执行权,释放锁。
sleep:释放执行权,不释放锁。
2,示例:
class Demo {
void show() {
synchronized(this) {
wait();//t0,t1,t2都挂在这里
}
}
void method() {
synchronized(this) { //t4拿执行权
notifyAll();//唤醒全部,t0,t1,t2
}//t4结束
}
}
这时t0,t1,t2都已经进入到同步内,t0,t1,t2都有执行资格,但t4释放锁后,只有一个线程拿到锁,所以还能保证同步性。
14-10,停止线程的方式-定义标记
1,停止线程
(1)stop方法(已过时,不可用)
(2)run方法结束。
如何控制线程的任务结束呢?
任务中一般都会有循环结构,只要控制住循环就可以结束任务,控制循环结束通常以定义标记的形式完成。如:
class StopThread implements Runnable {
private boolean flag = true;
public void run() {
while(flag) {
System.out.println(Thread.currentThread().getName()+"....");
}
}
public void setFlag() {
flag = false;
}
}
class StopThreadDemo {
public static void main(String[] args) {
StopThread st = new StopThread();
Thread t1 = new Thread(st);
Thread t2 = new Thread(st);
t1.start();
t2.start();
int num = 1;
for(;;) {
//定义循环结束条件
if(++num == 50) {
/*
如果num=50,则把flag置为false,并退出无限循环。
将flag置为false,则run方法中的while(flag)为假,不再执行。
实现了用标记结束run方法。
*/
st.setFlag();
break;
}
System.out.println("main..." + num);
}
System.out.println("over");
}
}
14-11,停止线程的方式-Interrupt
1,如果线程处于了冻结状态,无法读取标记,该如何结束呢?
可以使用Interrupt方法将线程从冻结状态强制恢复到运行状态中来,让线程具备CPU的执行资格。Interrupt方法为强制动作,会发生InterruptedException异常,记得要处理。
例如:
class StopThread implements Runnable {
private boolean flag = true;
public synchronized void run() {
while(flag) {
//产生InterruptException异常,用try-catch处理
try {
//t1,t2进入后会被wait,用后面的interrupt方法中断wait,
//是t1,t2可以继续执行输出,并把标记改为false,是线程结束。
wait();
}catch(InterruptedException e) {
System.out.println(Thread.currentThread().getName()+"..."+e);
flag = false;
}
System.out.println(Thread.currentThread().getName() + ".....");
}
}
public void setFlag() {
flag = false;
}
}
class StopThreadDemo {