二 java------线程---线程的控制

线程一些小知识的整理。

一:设置线程的优先级
需求: 定义两个线程,对线程的优先级别进行设置,并运行!
技能: 引入线程的控制方法--- setPrirority(int i)  getPrirority();
  1.设计线程的优先级别的方法
     1.1 public final void setPriority(int newPriority)
         注意: 被final修饰的方法,只能被继承不能被重写!(也可以重载)
              参数---int newPriority    1   5    10
              在Thread当中,存在以下几个常量:
              线程可以具有的最高优先级。
                 public static final int MAX_PRIORITY   10
              分配给线程的默认优先级。
                 public static final int NORM_PRIORITY  5
              线程可以具有的最低优先级。 
                 public static final int MIN_PRIORITY   1  
         问题: 能否直接写整数常量?  可以的
         问题: 写入负整数以及0会出现什么情况? 输入的是7或8这些会出现什么情况?
              推荐怎么传入实参?
              1.输入负数,虽然符合int 的取值范围,但是在后台运行时,出现非法参数异常---IllegalArgumentException
              2.发现:优先级别的范围: 1--10之内的,包括1也包括10
              3.以后在输入实参时,建议使用Thread类当当中的常量
                 Thread.MAX_PRIRORITY  Thread.MIN_PRIRORITY   Thread.NORE_PRIRORITY         
     1.2 public final int getPriority()
         发现:返回值类型是int类型  传入的是什么优先级,返回的就是多少。
   2.由于线程具有并发性以及随机性,即使设置的某个线程的优先级别最高,也不一定先执行!
      原因:   ① 随机性
            ② 每一个线程都会循环得到自己的时间片,都会抢CPU资源,谁抢到了谁先运行!   
      既然不能保证线程优先执行,为什么还要进行设置?
      原因:虽然不能保证优先界别最高的线程先执行,但是他优先执行的概率是很大的!
   3.main方法也是属于线程,它的优先级别是默认的,也就是5
代码区:
public class TestPriroprity {
 public static void main(String[] args) {
  
  //1.创建Runnable接口对象
     Runnable r1 = new Tiger();
     Runnable r2 = new Cat();
  //2.借助Thread类,创建线程对象
    Thread t1 = new Thread(r1);
    Thread t2 = new Thread(r2);
    //线程的优先级
//    t1.setPriority(Thread.MAX_PRIORITY);
//    t2.setPriority(Thread.MIN_PRIORITY);
    t1.setPriority(7);
    t2.setPriority(8);
    System.out.println(t1.getPriority());
    System.out.println(t2.getPriority());
    //获取main方法也就是主线程的名称和优先级别
    System.out.println(Thread.currentThread().getName());
    int pri=Thread.currentThread().getPriority();
    System.out.println("pri="+pri);
  //3.启动线程
    t1.start();
    t2.start();
 }
}
class Tiger  implements Runnable{
 @Override
 public void run() {
  System.out.println("Tiger线程优先级别是最高级---MAX_PRIRORITY");
 }
}
class Cat implements Runnable{
 @Override
 public void run() {
  System.out.println("Tiger线程优先级别是最低级---MIN_PRIRORITY");
 }
}
二:线程的强制加入
需求: 在你做一件好事的时候,即将完成,突然---半路杀出个程咬金
技能: 线程控制方法----强制加入
  1.强制加入的方法---join();
     public final void join() throws InterruptedException
     发现: 使用final修饰以及抛出了异常(中断异常)
  2.时时刻刻要记住----main方法也是一个线程
  3.思路步骤:
     3.1 先创建一个线程类(创建线程对象),最好实现Runnable接口
     3.2 重写run()方法,在run()方法内部,定义一个for循环(有限循环)
     3.3 在main方法当中,定义一个for循环---循环次数20次,当循环到10次的时候,另外一个线程强制加入!
       发现:只有强制加入的线程执行完毕之后,其他的线程才能继续运行,反之,其他线程不能执行!
代码区:
public class TestJoinThread {
 //主方法也是一个线程
 public static void main(String[] args) {
  //创建ChengYaoJin线程对象
  Runnable r = new ChengYaoJin();
  Thread t = new Thread(r);
  for(int i=1;i<=20;i++){
   System.out.println("牛荣君超级大美女-----自恋"+i);
   try {
    Thread.sleep(1000);
   } catch (InterruptedException e1) {
    // TODO Auto-generated catch block
    e1.printStackTrace();
   }
   //当循环到第10次的时候,阚天阳来了....
   if(i==10){
    //启动线程
    t.start();
    //强制加入,由于此方法抛出异常,所以在调用时必须对异常进行处理----try catch捕捉异常
    try {
     t.join();
    } catch (InterruptedException e) {
     // TODO Auto-generated catch block
     e.printStackTrace();
    }
   } 
  }
 }
}
class ChengYaoJin  implements Runnable{

 //重写接口当中的run()方法
 public void run() {
    //因为run方法是线程的主体,所以要把核心代码放入到此方法中
  for(int i=1;i<=10;i++){
   System.out.println("谁拿走了我的八块腹肌----阚天阳"+i);
   try {
    Thread.sleep(500);
   } catch (InterruptedException e) {
    // TODO Auto-generated catch block
    e.printStackTrace();
   }
  }
  
 }
 
}
三:线程休眠:
需求1: 运动会---裁判 预备    1  2  3  开始
技能1: 引入线程的控制方法---线程休眠
  需求2: 定义一个时间,时间的格式: HH:mm:ss,每隔一秒进行打印一次!
  技能2: 引入线程的控制方法---线程休眠
  1.线程休眠的方法
     public static void sleep(long millis)throws InterruptedException
     发现: 此方法使用static修饰,所以可以使用类名称直接调用。此方法抛出异常,所以在调用时必须处理异常---捕捉异常。
  2.此方法的作用
     2.1 线程进行堵塞状态,休眠时间结束,会在次进入就绪状态,参与分配CPU资源,运行线程!
     2.2 可以被变相的看成是一个转换器---例如: 两个线程交叉运行   线程A运行一次,线程B运行一次,以此类推
         体现: 在定义两个线程时,在run方法当中,插入线程休眠的方法,具体看实例!
              如果想具体的保证两个线程的交叉允许,可以使用同步锁完成!
  3.方法的参数
      long millis --- 毫秒数    单位的换算   1000毫米=1秒
代码区:
import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.Date;
public class TestSleepThread {
 public static void main(String[] args) {
  //1.时间格式化类---DateFormat   SimpleDateFormat()
     DateFormat  df = new SimpleDateFormat("HH:mm:ss");
  //2.定义while循环,目的: 打印时间
     while(true){
      //打印时间,必须有一个Date类对象
        Date d = new Date();
      //DateFormat类存在一个format(Date d) 返回值是String类型
        String now=df.format(d);
        System.out.println(now);
        //每隔一秒进行打印输出时间
        try {
     Thread.sleep(1000);
    } catch (InterruptedException e) {
     // TODO Auto-generated catch block
     e.printStackTrace();
    }
     }
  
 }
 public static void show(){
  //1.裁判应该先喊: 各就各位    预备
    System.out.println("各就各位    预备..............");
    //2.等待三秒,三秒已过,立即开始执行....
    for (int i = 1; i < 4; i++) {
     System.out.println(i);
     //每一次输出i的值,需要间隔一秒
     try {
      Thread.sleep(1000);
     } catch (InterruptedException e) {
      // TODO Auto-generated catch block
      e.printStackTrace();
     }
    }
    //3.开始
    System.out.println("开始....................");
 }
}
四:线程的礼让
需求: 古装剧------西门大官人    林娘子    潘娘子, 定义两个线程,每一个线程要交叉运行,一个线程喊: 官人  一个线程喊: 娘子   
技能: 线程礼让的方法----yield();
  1.线程礼让----yield方法
     暂停当前正在执行的线程对象,并执行其他线程。 
     public static void yield()
     发现: 此方法没有抛出异常,同时使用static修饰,所以类名称可以直接调用!
     特点: 暂停正在执行的线程,让其他线程先执行,而且此方法不是阻塞线程,而是将线程转入---就绪状态,不是阻塞状态
     continue --- 结束本次循环,执行下一次循环
     yield()  --- 让出当前的CPU资源,让其他的线程优先执行!
  2.线程要交叉运行--- 解决方案
      2.1 使用的是线程的休眠---发现: 并不一定按照交叉运行,可能是某一个线程执行完毕,另外一个线程才执行。
      2.2 使用线程的礼让,但是呢,它也不能保证线程的交叉运行,只是一定程度上,可以实现,如果想线程之间真正的交叉允许,需要使用线程同步。
  3.步骤:
      3.1 创建线程---一个线程充当: 男友   -- 官人
                   一个线程充当: 女友   -- 娘子  
          实现的方式: 先通过继承的方式,在使用实现Runnable接口的方式
      3.2 要重写run()方法---不管是继承Thread类也好,还是实现Runnable接口也好,都要重写run()方法
          原因: 因为run()方法,是线程的主体,核心代码放入到此方法中。
      3.3 在重写的过程当中,可以使用线程休眠也可以使用线程礼让
      3.4 在main方法当中,创建线程,并启动线程!
public class TestYieldThread {
 public static void main(String[] args) {
  //1.创建线程对象
      Thread t1 = new GuanRen();
      Thread t2 = new NiangZi();
  //2.为线程命名
      t1.setName("\t潘娘子");
      t2.setName("西门大官人");
  //3.启动线程
      t1.start();
      t2.start();
      
 }

}
//创建线程类,通过继承Thread类实现
class GuanRen  extends Thread{
 //重写run()方法
 public void run(){
  //for循环语句     目的: 为了实现交叉运行,肯定有一个定喊话次数 
  for(int i=1;i<=10;i++){
   System.out.println(this.getName()+"喊:官人.....");
   //切换 -- sleep();
//   try {
//    Thread.sleep(1000);
//   } catch (InterruptedException e) {
//    // TODO Auto-generated catch block
//    e.printStackTrace();
//   }
   //线程的礼让
   Thread.yield();
  }
 }
 
}
class NiangZi extends Thread{
 //重写run()方法
  public void run(){
   //for循环语句     目的: 为了实现交叉运行,肯定有一个定喊话次数 
   for(int i=1;i<=10;i++){
    System.out.println(this.getName()+"喊:娘子.....");
    //切换 -- sleep();
//    try {
//     Thread.sleep(1000);
//    } catch (InterruptedException e) {
//     // TODO Auto-generated catch block
//     e.printStackTrace();
//    }
    //线程的礼让
    Thread.yield();
   }
  }
}
五:设置线程为后台线程
需求: 在main方法当中,创建线程,并设置线程为后台线程,main方法运行结束之后,后台线程也随之结束!
技能: 线程的控制方法-----后台线程。
  1.设置线程为后台线程
      public final void setDaemon(boolean on)
      将该线程标记为守护线程或用户线程
      发现:1.此方法使用final修饰  2. 没有抛出异常  3. 参数类型是布尔值,如果是true则设置为后台线程,反之,是前台线程。
  2.后台线程---前台线程
     后台线程又被称为守护线程,前台线程又被称为用户线程!
     注意: 咱们一般创建的线程都是用户线程,特别说明: main方法时一个用户线程
          后台线程----最典型的例子就是GC---垃圾回收器
  3.设置线程为后台线程,必须是在线程的启动之前,也就是start()方法之前进行设置!
代码区:
public class TestSetDeamonThread {
    //主方法不仅是一个线程,还是一个用户线程(前台线程)
 public static void main(String[] args) {
  //1.创建线程对象
     Runnable r = new QianJinHui(); //目的: 为Thread类创建对象,做准备
     Thread t = new Thread(r); //根据构造方法,传入Runnable接口对象
  //2.设置后台线程
     t.setDaemon(true);
  //3.启动线程
    t.start();
  //4.也写一个for循环,for循环执行结束,后台线程也随之结束,即使后台线程中的run方法嵌套了一个死循环,也要结束
    for(int i=1;i<=5;i++){
     System.out.println("周日计划----休眠"+i);
    }
 }
}
//创建一个线程类
class QianJinHui implements Runnable{

 //重写run()方法
 public void run() {
  //为了体现出: 前台线程结束之后,后台线程也随之结束,写一个死循环
  while(true){
   System.out.println("上课玩手机,该罚-----十个俯卧撑!");
  }
 }
}

原博地址(也是我,O(∩_∩)O哈哈~):http://m15231417197.lofter.com/

练习代码地址(嘿嘿嘿):https://download.csdn.net/download/m15231417197/10716486

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值