zoukankan      html  css  js  c++  java
  • java的多线程之四(线程的操作)

    本文来自:高爽|Coder,原文地址:http://blog.csdn.net/ghsau/article/details/17560467,转载请注明。

    线程中断

     
     线程中断涉及到三个方法,如下: 
        

           interrupt()方法用于中断线程,通常的理解来看,只要某个线程启动后,调用了该方法,则该线程不能继续执行了,来看个小例子:

     
     1 public class InterruptTest {
     2     public static void main(String[] args) throws InterruptedException {
     3         MyThread t = new MyThread("MyThread");
     4         t.start();
     5         Thread.sleep(100);// 睡眠100毫秒
     6         t.interrupt();// 中断t线程
     7     }
     8 }
     9 class MyThread extends Thread {
    10     int i = 0;
    11     public MyThread(String name) {
    12         super(name);
    13     }
    14     public void run() {
    15         while(true) {// 死循环,等待被中断
    16             System.out.println(getName() + getId() + "执行了" + ++i + "次");
    17         }
    18     }
    19 }

           运行后,我们发现,线程t一直在执行,没有被中断,原来interrupt()是骗人的,汗!其实interrupt()方法并不是中断线程的执行,而是为调用该方法的线程对象打上一个标记,设置其中断状态为true,通过isInterrupted()方法可以得到这个线程状态,我们将上面的程序做一个小改动:

     
     1 public class InterruptTest {
     2     public static void main(String[] args) throws InterruptedException {
     3         MyThread t = new MyThread("MyThread");
     4         t.start();
     5         Thread.sleep(100);// 睡眠100毫秒
     6         t.interrupt();// 中断t线程
     7     }
     8 }
     9 class MyThread extends Thread {
    10     int i = 0;
    11     public MyThread(String name) {
    12         super(name);
    13     }
    14     public void run() {
    15         while(!isInterrupted()) {// 当前线程没有被中断,则执行
    16             System.out.println(getName() + getId() + "执行了" + ++i + "次");
    17         }
    18     }
    19 }

           这样的话,线程被顺利的中断执行了。很多人实现一个线程类时,都会再加一个flag标记,以便控制线程停止执行,其实完全没必要,通过线程自身的中断状态,就可以完美实现该功能。如果线程在调用 Object 类的 wait()、wait(long) 或 wait(long, int) 方法,或者该类的 join()、join(long)、join(long, int)、sleep(long) 或 sleep(long, int) 方法过程中受阻,则其中断状态将被清除,它还将收到一个 InterruptedException。 我们可以捕获该异常,并且做一些处理。另外,Thread.interrupted()方法是一个静态方法,它是判断当前线程的中断状态,需要注意的是,线程的中断状态会由该方法清除。换句话说,如果连续两次调用该方法,则第二次调用将返回 false(在第一次调用已清除了其中断状态之后,且第二次调用检验完中断状态前,当前线程再次中断的情况除外)。

     

    线程让步

      
     

           线程让步用于正在执行的线程,在某些情况下让出CPU资源,让给其它线程执行,来看一个小例子:

     
     1 public class YieldTest {
     2     public static void main(String[] args) throws InterruptedException {
     3         // 创建线程对象
     4         YieldThread t1 = new YieldThread("t1");
     5         YieldThread t2 = new YieldThread("t2");
     6         // 启动线程
     7         t1.start();
     8         t2.start();
     9         // 主线程休眠100毫秒
    10         Thread.sleep(100);
    11         // 终止线程
    12         t1.interrupt();
    13         t2.interrupt();
    14     }
    15 }
    16 class YieldThread extends Thread {
    17     int i = 0;
    18     public YieldThread(String name) {
    19         super(name);
    20     }
    21     public void run() {
    22         while(!isInterrupted()) {
    23             System.out.println(getName() + "执行了" + ++i + "次");
    24             if(i % 10 == 0) {// 当i能对10整除时,则让步
    25                 Thread.yield();
    26             }
    27         }
    28     }
    29 }

           输出结果略,从输出结果可以看到,当某个线程(t1或者t2)执行到10次、20次、30次等时,就会马上切换到另一个线程执行,接下来再交替执行,如此往复。注意,如果存在synchronized线程同步的话,线程让步不会释放锁(监视器对象)

     

    线程睡眠

     
         

           线程睡眠的过程中,如果是在synchronized线程同步内,是持有锁(监视器对象)的,也就是说,线程是关门睡觉的,别的线程进不来,来看一个小例子:

     
     1 public class SleepTest {
     2     public static void main(String[] args) {
     3         // 创建共享对象
     4         Service service = new Service();
     5         // 创建线程
     6         SleepThread t1 = new SleepThread("t1", service);
     7         SleepThread t2 = new SleepThread("t2", service);
     8         // 启动线程
     9         t1.start();
    10         t2.start();
    11     }
    12     
    13 }
    14 class SleepThread extends Thread {
    15     private Service service;
    16     public SleepThread(String name, Service service) {
    17         super(name);
    18         this.service = service;
    19     }
    20     public void run() {
    21         service.calc();
    22     }
    23 }
    24 class Service {
    25     public synchronized void calc() {
    26         System.out.println(Thread.currentThread().getName() + "准备计算");
    27         System.out.println(Thread.currentThread().getName() + "感觉累了,开始睡觉");
    28         try {
    29             Thread.sleep(10000);// 睡10秒
    30         } catch (InterruptedException e) {
    31             return;
    32         }
    33         System.out.println(Thread.currentThread().getName() + "睡醒了,开始计算");
    34         System.out.println(Thread.currentThread().getName() + "计算完成");
    35     }
    36 }

    线程合并

     
          
           线程合并是优先执行调用该方法的线程,再执行当前线程,来看一个小例子:
     
     1 public class JoinTest {
     2     public static void main(String[] args) throws InterruptedException {
     3         JoinThread t1 = new JoinThread("t1");
     4         JoinThread t2 = new JoinThread("t2");
     5         t1.start();
     6         t2.start();
     7         t1.join();
     8         t2.join();
     9         System.out.println("主线程开始执行!");
    10     }
    11 }
    12 class JoinThread extends Thread {
    13     public JoinThread(String name) {
    14         super(name);
    15     }
    16     public void run() {
    17         for(int i = 1; i <= 10; i++)
    18             System.out.println(getName() + getId() + "执行了" + i + "次");
    19     }
    20 }
           t1和t2都执行完才继续主线程的执行,所谓合并,就是等待其它线程执行完,再执行当前线程,执行起来的效果就好像把其它线程合并到当前线程执行一样
     

    线程优先级

     
           线程最低优先级为1,最高优先级为10,看起来就有10个级别,但这10个级别能不能和CPU对应上,还未可知,Thread类中提供了优先级的三个常量,如下:
    java.lang.Thread
    public static final int MAX_PRIORITY 10
    public static final int MIN_PRIORITY 1
    public static final int NORM_PRIORITY 5
           我们创建线程对象后,如果不显示的设置优先级的话,默认为5。优先级可以看成一种特权,优先级高的,获取CPU调度的机会就大,优先级低的,获取CPU调度的机会就小,这个和我们现实生活很一样啊,优胜劣汰。线程优先级的示例就不写了,比较简单。
     

    wait()和sleep()区别

     
           区别太大了,但是在Java线程面试题中是很常见的问题,相信你阅读过本专栏后,能够轻松的解答,这里不再赘述。
  • 相关阅读:
    POJ 2236 Wireless Network(并查集)
    POJ 2010 Moo University
    POJ 3614 Sunscreen(贪心,区间单点匹配)
    POJ 2184 Cow Exhibition(背包)
    POJ 1631 Bridging signals(LIS的等价表述)
    POJ 3181 Dollar Dayz(递推,两个long long)
    POJ 3046 Ant Counting(递推,和号优化)
    POJ 3280 Cheapest Palindrome(区间dp)
    POJ 3616 Milking Time(dp)
    POJ 2385 Apple Catching(01背包)
  • 原文地址:https://www.cnblogs.com/lintong/p/4373084.html
Copyright © 2011-2022 走看看