1. join线程:

在线程执行过程中,有时想让另一个线程先执行,比如将一大问题分割成许多小问题,给每一个小问题分配线程,但所有小问题处理完后再让主线程进一步操作。此时我们可以在主线程中调用其它线程的join()方法,以阻塞调用线程(在这里为主线程)。

示例代码:

   1: package org.frzh.thread;

   2:  

   3: public class JoinThread extends Thread{

   4:     //提供一个有参构造器,用来设置线程的名字

   5:     public JoinThread(String name) {

   6:         super(name);

   7:     }

   8:     

   9:     public void run() {

  10:         for (int i = 0; i < 100; i++) {

  11:             System.out.println(getName() + " " + i);

  12:         }

  13:     }

  14:     

  15:     public static void main(String[] args) {

  16:         //启动子线程

  17:         new JoinThread("新线程").start();

  18:         for (int i = 0; i < 100; i++) {

  19:             if (i == 20) {

  20:                 JoinThread jt = new JoinThread("被join的线程");

  21:                 jt.start();

  22:                 //main线程调用了jt线程的join方法,则main线程必须等待jt执行完之后才能执行

  23:                 try {

  24:                     jt.join();

  25:                 } catch (InterruptedException e) {

  26:                     // TODO Auto-generated catch block

  27:                     e.printStackTrace();

  28:                 }

  29:             }

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

  31:         }

  32:     }

  33: }

本来有三套线程(两条子线程和一main线程),当i=20后,main线程被阻塞必须等到“被join线程”执行完之后才有机会执行,所以此后只有两条线程执行。

join()方法的三种重载形式:

join():等待被join线程执行完;

join(long millis):等待被join线程执行最长为mills豪秒,在这之后即使被join线程没有执行完也不再等待;

join(long millis, int nanos):等待被join线程执行最长时间为millis毫秒+nanos微秒。(此方法基本用不上)。

2:后台线程:

有一种线程,他是在后台运行,他的任务是为其他线程服务,这种线程被称为“后台线程”、“守护线程”或“精灵线程”。当所有前台线程都死亡后,后台线程会自动死亡。

示例代码:

   1: package org.frzh.thread;

   2:  

   3: public class DaemonThread extends Thread{

   4:     public void run() {

   5:         for (int i = 0; i < 1000; i++) {

   6:             System.out.println(getName() + " " +i);

   7:         }

   8:     }

   9:     

  10:     public static void main(String[] args) {

  11:         DaemonThread dt = new DaemonThread();

  12:         //将此线程设置为后台线程

  13:         dt.setDaemon(true);

  14:         dt.start();

  15:         for (int i = 0; i < 10; i++) {

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

  17:         }

  18:         //前台线程结束,那么后台线程dt也会结束,所以它执行不到999

  19:     }

  20: }

主线程默认是前台线程,前台线程创建的子线程默认是前台线程,后台线程创建的子线程默认是后台线程。

3.线程睡眠(sleep):

前面的join方法是让调用线程等待被join线程执行完之后再继续执行,而sleep()方法是让调用线程阻塞一段时间后再重新进入就绪状态等待被调度。因此它通常用来暂停程序的执行。

示例代码:

   1: package org.frzh.thread;

   2:  

   3: import java.util.Date;

   4:  

   5: public class SleepThread{

   6:     public static void main(String[] args) {

   7:         for (int i = 0; i < 10; i++) {

   8:             System.out.println("当前时间:" + new Date());

   9:             try {

  10:                 Thread.sleep(1000);

  11:             } catch (InterruptedException e) {

  12:                 // TODO Auto-generated catch block

  13:                 e.printStackTrace();

  14:             }

  15:         }

  16:     }

  17: }

sleep()方法的两种重载方式:

static void sleep(long millis):让当前线程暂停millis毫秒,并进入阻塞状态。该方法会受到系统计时器和线程调度器的精度和准度的影响。

static void sleep(long millis, int nanos):暂停mills毫秒+nanos微秒,并进入阻塞状态,同样会受系统计时器和线程调度器的精度和准度的影响。基本不用。

4.线程让步(yield):

yield()方法和sleep方法有点类似,它同样可以使当前正在运行的线程暂停,但他不会阻塞该线程,只是将他转入就绪状态(注意不是阻塞状态)。yield()方法只会让和它同等优先级或更高优先级的线程有被执行的机会,所以某一线程调用该方法后可能又被重新调度回来继续执行。

示例代码:

   1: package org.frzh.thread;

   2:  

   3: public class YieldThread extends Thread{

   4:     public YieldThread() {

   5:         

   6:     }

   7:     public YieldThread(String name) {

   8:         super(name);

   9:     }

  10:     public void run() {

  11:         for (int i = 0; i < 100; i++) {

  12:             System.out.println(getName() + " " +i);

  13:             if (i == 20) {

  14:                 //当前线程让步

  15:                 Thread.yield();

  16:             }

  17:         }

  18:         

  19:     }

  20:     

  21:     public static void main(String[] args) {

  22:         //启动两条并发线程

  23:         YieldThread yt1 = new YieldThread("高级");

  24:         //设置yt1为最高优先级

  25:         yt1.setPriority(Thread.MAX_PRIORITY);

  26:         yt1.start();

  27:         YieldThread yt2 = new YieldThread("低级");

  28:         yt2.setPriority(Thread.MIN_PRIORITY);

  29:         yt2.start();

  30:         /*

  31:          * 如果不给线程设置优先级,则两个线程的优先级是相同的,所以两线程会交替执行,当调用yield后会让另一个线程执行;

  32:          * 但是,给两个线程分别设置上述优先级之后,刚开始高级线程执行,当i=20时,调用yield,但由于yield方法只会

  33:          * 给和它同优先级或更高优先级的线程执行机会,所以此时仍是高级线程执行,而不会让给低级线程

  34:          */

  35:     }

  36: }

5:改变线程的优先级:

此举比较简单,只需调用调用实例方法setPriority(int priority)方法即可。每个线程默认与其父线程的优先级相同,main线程默认具有普通优先级(5)。java提供1~10个优先级,也可以使用三个静态常量:

MAX_PRIORITY:10

MIN_PRIORITY:1

NORM_PRIORITY:5

注意的是:尽管java提供10个优先级,但是不同的系统支持的优先级不一样,所以尽量避免直接使用1~10之间的数字,而使用静态常量,以保证具有良好的可移植性。

最新文章

  1. less入门
  2. Sql Server 查看表修改记录
  3. npm 重点小结
  4. ssh默认端口更改后,如何正常使用git?
  5. 什么是侧翼区(flanking region)和侧翼区单核苷酸多态性(Flanking SNPs)
  6. webApi中参数传递
  7. 2013 Multi-University Training Contest 8
  8. php中使用PHPExcel操作excel(xls)文件
  9. 51nod 1021 石头归并
  10. SQLServer 复制中移除和加入公布而不初始化全部项目
  11. .net: 不能忽视的break——寻找VS2010和VS2012编译器的一个小区别
  12. POJ 3362 Protecting the Flowers
  13. mac中使用 sourcetree 的快速配置和git服务器登录
  14. PHP中域名绑定
  15. Android版数据结构与算法(一):基础简介
  16. c\c++里struct字节对齐规则
  17. ext遍历表单中所有输入项,并全部设置为只读
  18. 图解HTTPS协议
  19. ES集群
  20. 【BZOJ2427】[HAOI2010]软件安装(动态规划,Tarjan)

热门文章

  1. 基于excel9.h的excel处理
  2. jeasyui制作计划-搭建php运行环境
  3. 正三角形的外接圆面积,nyoj-274
  4. Oracle EBS-SQL (OM-2):检查OM常用表
  5. Unix/Linux环境C编程入门教程(29) 内存操作那些事儿
  6. linux下so动态库一些不为人知的秘密(中二)
  7. 【LeetCode练习题】Copy List with Random Pointer
  8. tomcat root dir log 配置
  9. OpenstackUbuntu
  10. Fast RCNN 学习