Java基础14--多线程(五)

2014-11-24 07:36:58 · 作者: · 浏览: 3
me + count; count++; System.out.println(Thread.currentThread().getName()); flag = true; //用消费者监视器唤醒一个消费者线程 consumer_con.signal(); }finally { lock.unlock(); } } public void out() { lock.lock(); try{ while(!flag) { try { consumer_con.swait(); }catch(InterruptedException e) {} } flag = false; //用生产者监视器唤醒一个生产者线程 producer_con.signal(); }finally { lock.unlock(); } } }

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 {