Java多线程3—线程的调度和runnable接口优点

来源:互联网 发布:淘宝天天特价库存数量 编辑:程序博客网 时间:2024/06/05 11:29

Java运行时系统实现了一个用于调度线程执行的线程调度器,用于确定某一时刻由哪一个线程在CPU上运行。在java技术中,线程通常是抢占式的而不需要时间片分配进程(分配给每个线程相等的CPU时间的进程)。抢占式调度模型就是许多线程处于可以运行状态(等待状态),但实际上只有一个线程在运行。该线程一直运行到它终止进入可运行状态(等待状态),或者另一个具有更高优先级的线程变成可运行状态。在后一种情况下,低优先级的线程被高优先级的线程抢占,高优先级的线程获得运行的机会。

Java线程调度器支持不同优先级线程的抢先方式,但其本身不支持相同优先级线程的时间片轮换。Java运行时系统所在的操作系统(例如:Windows2000)支持时间片的轮换,则线程调度器就支持相同优先级线程的时间片轮换。下面我们写一个例子程序简单的介绍一下:

class MultiThread

{

   public static void main(String[] args)

   {

      MyThread mt=new MyThread();

      Threadt = newThread(mt);

t.start();

      while(true)

      {

         System.out.println("main:"+Thread.currentThread().getName());

      }

   }

}

 

class MyThreadimplementsRunnable//extends Thread

{

   public void run()

   {

      while(true)

      {

         System.out.println(Thread.currentThread().getName());

      }

   }

}

//Thread-0

Thread-0

Thread-0

Thread-0

main:main

main:main

main:main

main:main

        循环输出结果,这里两个线程交替执行,但是并不是由于java虚拟机使其切换的,是由于操做系统的时间片原则,使两个线程交替执行。如果我们希望改变线程的优先级,可以调用Thread类的setPriority()方法改变。这个方法需要一个参数,系统提供了几个常量MAX_PRIORITY、MIX_PRIORITY我们在使用这个方法的时候需要传递其中一个参数。我们修改一下上面的代码:

Thread t = new Thread(mt);

t.setPriority(MAX_PRIORITY);//加上这行代码

t.start();

         这样程序的执行结果就是一直执行Thread-0,在我们退出的时候才会执行main:main。多说一句,一般情况下我们不去修改线程的优先级,而且线程的优先级的改变不一定在start()方法前,在线程启动后,我们也可以根据需要改变线程的优先级。

       下面我们来说一下实现runnable接口的优势,第一个优势我上篇文章已经说了就不多说了,大家可以去http://blog.csdn.net/mengxiangyue/article/details/6865741看看。第二个优势就是,如果我们的多个线程需要同时访问相同的数据,如果我们继承Thread类的话,就需要这个类创建的线程间的数据进行通信,但是如果我们实现runnable接口的话,就不用那么做(这里有点不对,并不是所有的实现runnable接口都不用通信)。下面我们用一个程序说明一下:

class MultiThread

{

   public static void main(String[] args)

   {

      MyThread mt=new MyThread();

      new Thread(mt).start();

      new Thread(mt).start();

      new Thread(mt).start();

      new Thread(mt).start();

      for(int i = 0;i<100;i++)

      {

         System.out.println("main:"+Thread.currentThread().getName());

      }

   }

}

 

class MyThreadimplementsRunnable//extends Thread

{

   int index=0;

      public void run()

      {

         for(int i = 0;i<100;i++)

         {

            System.out.println(Thread.currentThread().getName()+":"+index++);

         }

      } 

}

//Thread-0:0

Thread-3:3

main:main

Thread-2:2

Thread-1:1

Thread-2:6

main:main

Thread-3:5

Thread-0:4

Thread-3:9

main:main……

       结果是这四个线程输出了从0到399,虽然顺序不是按照1、2、3……这样,但是也没有问题,这个原因是因为线程执行时候操做系统时间片调度原则产生的。如果你在你的PC上运行这段代码,得到的结果也会不同。

         写这个的时候明显感到有的地方写的不妥,希望大家指出。