多线程——等待唤醒机制接着线程之间的通信, 这里有个问题, 同步了, 但是运行的话, 会执行一大片, 但是一般都是存一个,输出一个,
为什么会执行一大片?
一个线程可能一直拥有CPU的执行权;
如何解决?(参考代码)
这里可以用一个标记来标识(flag),当存一个完了之后, 就改变这个标识,当下次再执行时, 就不会再存了,
此时可以将这个线程1给冻结(sleep(时间(毫秒)),wait()),如果用sleep(),时间不确定, 所以就用wait(),当执行完了之后,
标识发生改变,再次执行时, 就处于冻结状态了,失去执行资格。
那什么时候恢复执行资格呢?
当另一个线程2进来将这个存的值,取走了, 就恢复执行资格,如何恢复?
当取走后, 标识再次发生改变,然后用notify(),唤醒线程1,此时如果这个线程2再次执行时, 由于没有了值, 那么就将线程2冻结,wait()。
这个过程就是线程间的等待唤醒机制。
代码如下:
- class Res //共享资源的类
- {
- String name;
- String sex;
- boolean flag=false;
- }
- /*
- 等待的线程在哪里呢?
- 线程运行的时候, 内存中会建立一个叫做线程池的,等待线程都存放在线程池中,
- 当notify的时候, 都是唤醒的是线程池中的线程,当线程池中有许多的线程都在等待,
- 通常是唤醒第一被等待的线程, 按照顺序来叫醒
- */
- class Input implements Runnable//需要用到一个资源,
- {
- private Res r;
- Input(Res r){//传递过来一个资源类的对象
- this.r=r;
- }
- public void run(){
- int x=0;
- while(true)
- {
- synchronized(r)//这里需要同步,
- {
- if(r.flag){
- try{r.wait();}catch(Exception e){}//当为真时, 就等待, 不能再传值了,因为已经有值
- }
- if(x==0){
- r.name="mike";
- r.sex="man";
- }
- else{
- r.name="小王";
- r.sex="女女女女女女";
- }
- x=(x+1)%2;
- r.flag=true;
- r.notify();//在线程池中叫醒Output线程
- }
- }
- }
- }
- class Output implements Runnable
- {
- private Res r;
- Output(Res r){
- this.r=r;
- }
- public void run(){
- while(true)
- {
- synchronized(r){//这里也需要同步,并且锁需要是同一个锁。
- if(!r.flag){
- try{r.wait();}catch(Exception e){}
- }
- //Wait(), notify(), notifyAll(), 全部用在同步中,因为需要锁必须标识wait()线程所处的锁
- System.out.println(r.name+"....."+r.sex);
- r.flag=false;
- r.notify();
- }
- }
- }
- }
- class ThreadInputOutput
- {
- public static void main(String[] args)
- {
- Res r=new Res();
- Input in=new Input(r);
- Output out=new Output(r);
- Thread t1=new Thread(in);
- Thread t2=new Thread(out);
- t1.start();
- t2.start();
- }
- }
复制代码
|
|