我之见--线程调度基本知识

           之前我们已经学习过了,线程的一个主要知识:资源共享;其实线程还有另外一个主要的内容就是线程之间的调度,一般而言线程的执行是要获取cpu,可能大家以为线程的调度无非就是Cpu的调度,其实这并不是这个意思,对于Cpu的调度,我们能做的只是为线程设置优先级setPriority,所谓优先级:对资源竞争的一个辨别依据,就是说当多个线程竞争资源时,具有较高优先级的线程会优先执行。现实使用的效果并没有我们想像的那样,优先级高的线程会被提前执行。因为线程优先级取决于操作系统最终对线程的调试,并不一定严格相同。具体可以参考:JVM关于线程调度。

    下面我们一起来学习一下,怎样通过线程的等待,睡眼,让步等实现线程的调度,java本身就能很好的支持多线程的 从Object类的 wait,Notify方法。下面我们来看一下具体api:

void notify() 
          唤醒在此对象监视器上等待的单个线程。 
 void notifyAll() 
          唤醒在此对象监视器上等待的所有线程。 
 void wait() 
          导致当前的线程等待,直到其他线程调用此对象的 notify() 方法或 notifyAll() 方法。
 void wait(long timeout) 
          导致当前的线程等待,直到其他线程调用此对象的 notify() 方法或 notifyAll() 方法,或者超过指定的时间量。 
 void wait(long timeout, int nanos) 
          导致当前的线程等待,直到其他线程调用此对象的 notify() 方法或 notifyAll() 方法,或者其他某个线程中断当前线程,或者已超过某个实际时间量
       wait 一般是notify 一起使用, wait是使线程进入等待,同时会释放获取的同步锁;有等待必然有唤醒,notifyall就是唤醒在此监视器上面的等待的线程,注意:notify和notifyAll区别:

 1. 如果监视器有多个线程在等待,Notify 唤醒只会唤醒其中的一条线程,但具体是那条线程是随机的。

 2.如果监视器只有一个线程等待,就使用notify唤醒线程。

 3.如果监视器有多个线程在等待,尽量使用notityAll来唤醒,这样对于每个线程来说都是公平,很多人以为这样会造成资源的浪费,如果多个线程都在等待同一个资源,唤醒的时候,只有一个线程能得到满足,其他线程很快就进入wait了。但这样的浪费是可以理解的,如果不想造成这样的浪费,尽量把共享资源的范围减小,同时使用不同的监视器。

     说了那么多,我们还是来看一下例子:

    

package javaThread;

public class WaitThread {

    public static void main(String[] args) {

        System.out.println("test main begint ");
        Thread notifyThread = new NotifyThread("notify thread");

        WatingThread waitThread = new WatingThread("wait Thread", notifyThread);

        waitThread.start();

        notifyThread.start();

    }

    static class NotifyThread extends Thread {
        private String mName;

        public NotifyThread(String name) {
            mName = name;
        }

        @Override
        public void run() {
            super.run();
            synchronized (this) {
                System.out.println(" thred name begint " + mName);
                for (int i = 0; i < 100; i++) {
                    System.out.println(" thred name count " + mName + " " + i);
                }
                notify();
                System.out.println(" thred name end" + mName);
            }
        }
    }

    static class WatingThread extends Thread {
        private String mName;
        private Thread mThread;

        public WatingThread(String name, Thread t) {
            mName = name;
            mThread = t;
        }

        @Override
        public void run() {
            super.run();
            synchronized (mThread) {

                System.out.println(" thred name begint " + mName);
                try {
                    mThread.wait();
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }

                for (int i = 0; i < 80; i++) {
                    System.out.println(" thred name count " + mName + " " + i);
                }

                System.out.println(" thred name end" + mName);
            }
        }
    }
}
输出:

test main begint 
 thred name begint wait Thread
 thred name begint notify thread
 thred name count notify thread 0
 thred name count notify thread 1
 ...................................
 thred name endnotify thread
 thred name count wait Thread 0
 thred name count wait Thread 1
 thred name count wait Thread 2
 ............................................
 thred name endwait Thread
还一点也要注意: notifyall或者notify必须要先获取监视器,否则会出现异常:
java.lang.IllegalMonitorStateException: current thread not owner  at java.lang.Object.notifyAll(Native Method)
  以上就是线程调度中最基础的知识。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值