Java基础知识十五:Thread多线程两种实现方式,设置和获取线程名称,两种线程调度模型、线程控制三种方式、线程生命周期

Thread

1、多线程的实现方式1

方式一:继承Thread类

1、定义一个类MyThread继承Thread

2、在MyThread类中重写run()方法

3、创建MyThread类的对象

4、启动线程

注:void start() 导致此线程开始执行,java虚拟机调用此线程的run()方法

两个小问题:

1、 为什么要重写run()方法? 因为run()方法是用来封装被线程执行的代码

2、 run()与start()的区别?

区别1:run()封装线程执行的代码,直接调用,相当于普通方法

区别2:start()启动线程,然后由jvm调用此线程的run()方法

public class MyThread extends Thread {
   @Override
   public void run() {
       super.run();
       for(int i = 0;i<100;i++){
           System.out.println(i);
       }
   }
}

public class MyThreadDemo1 {
   public static void main(String[] args) {
       MyThread mt1 = new MyThread();
       MyThread mt2 = new MyThread();
      /* mt1.run();
       mt2.run();*/
      mt1.start();
      mt2.start();
   }
}

2、设置和获取线程名称

1. void setName(String name) 将此线程的名称更改为等于参数name

2. String getName() 返回此线程的名称

public class MyThread extends Thread {
   //无参构造
   public MyThread() {
   }
   //带参构造
   public MyThread(String name) {
       super(name);
   }
   @Override
   public void run() {
       super.run();
       for(int i = 0;i<100;i++){
           System.out.println(getName()+":"+i);//获取线程名称
       }
   }
}

public class MyThreadDemo1 {
   public static void main(String[] args) {
       MyThread mt1 = new MyThread();
       MyThread mt2 = new MyThread();
      /* mt1.run();
       mt2.run();*/
      mt1.setName("beijing");//设置线程名称
      mt2.setName("shanghai");//无参构造赋值

       MyThread mt3 = new MyThread("hangzhou");//调用带参构造方法
       MyThread mt4 = new MyThread("xian");

      mt1.start();
      mt2.start();

       mt3.start();
       mt4.start();
       //获取main()方法线对象名称
       System.out.println(Thread.currentThread().getName());
   }
}

3、线程调度

线程调度有2种调度模型:

1. 分时调度模型:所有线程轮流使用CPU的使用权,平均分配每个线程占用CPU的时间片

2. 抢占式调度模型:优秀让优先级高的线程使用CPU,如果线程的优先级相同,那么随机选择一个,优先级高的线程获取的CPU时间片相对多一些

注:Java使用的是抢占式调度模型

Thread类中设置和获取线程优先级的2个方法:

1. Public final int getPriority() 返回线程的优先级

2. Public final void setPriority(int newPriority) 更改此线程的优先级

优先级范围:

1. 线程优先级的默认值:5

2. MIN_PRIORITY: 线程优先级的最小值1

3.MAX_PRIORITY: 线程优先级的最大值10

public class ThreadPriority extends Thread{
   @Override
   public void run() {
       super.run();
       for(int i = 0;i<100;i++){
           System.out.println(getName()+":"+i);//获取线程名称
       }
   }
}

public class ThreadPriorityDemo1{
   public static void main(String[] args) {
       ThreadPriority tp1 = new ThreadPriority();
       ThreadPriority tp2 = new ThreadPriority();
       ThreadPriority tp3 = new ThreadPriority();
       tp1.setName("beijing");
       tp2.setName("hangzhou");
       tp3.setName("shengzhen");
       System.out.println(tp1.getPriority());
       System.out.println(tp2.getPriority());
       System.out.println(tp3.getPriority());
       tp3.setPriority(1); // 设置线程优先级
       tp1.start();
       tp2.start();
       tp3.start();
   }
}

4、线程控制

常用三种方式:

1、 static void sleep(long milis) : 使用当前正在执行的线程停留(暂停执行)指定毫秒

2、 Void join() : 等待这个线程死亡

3、 Void setDaemon(boolean on) : 将此线程标记为守护线程,当运行的线程都是守护线程时,Java虚拟机退出

//案例一
public class ThreadSleep extends Thread {
   @Override
   public void run() {
       super.run();
       for(int i = 0;i<100;i++){
           System.out.println(getName()+":"+i);//获取线程名称
           try {
               Thread.sleep(1000);
           } catch (InterruptedException e) {
               e.printStackTrace();
           }
       }
   }
}

//static void sleep(long milis) : 使用当前正在执行的线程停留(暂停执行)指定毫秒
public class ThreadSleepDemo {
   public static void main(String[] args) {
       ThreadSleep ts1 = new ThreadSleep();
       ThreadSleep ts2 = new ThreadSleep();
       ThreadSleep ts3 = new ThreadSleep();
       ts1.setName("beijing");
       ts2.setName("hangzhou");
       ts3.setName("shengzhen");
       ts1.start();
       ts2.start();
       ts3.start();
}

//案例二
public class ThreadJoin extends Thread{
   @Override
   public void run() {
       super.run();
       for(int i = 0;i<100;i++){
           System.out.println(getName()+":"+i);//获取线程名称
       }
   }
}

//Void join() : 等待这个线程死亡
public class ThreadJoinDemo {
   public static void main(String[] args) throws InterruptedException {
       ThreadJoin tj1 = new ThreadJoin();
       ThreadJoin tj2 = new ThreadJoin();
       ThreadJoin tj3 = new ThreadJoin();
       tj1.setName("beijing");
       tj2.setName("hangzhou");
       tj3.setName("shengzhen");
       tj1.start();
       tj1.join(); //等调用的线程完毕后,其它线程才能执行
       tj2.start();
       tj3.start();
   }
}

//案例三
public class ThreadDaemon extends Thread {
   @Override
   public void run() {
       super.run();
       for (int i = 0; i < 100; i++) {
           System.out.println(getName()+":"+i);
       }
   }
}

//Void setDaemon(boolean on) : 将此线程标记为守护线程,当运行的线程都是守护线程时,Java虚拟机退出
public class ThreadDaemonDemo {
   public static void main(String[] args) {
       ThreadDaemon td1 = new ThreadDaemon();
       ThreadDaemon td2 = new ThreadDaemon();
       ThreadDaemon td3 = new ThreadDaemon();
       td1.setName("beijing");
       td2.setName("shengzhen");
       //设置主线程为hangzhou
       Thread.currentThread().setName("hangzhou");

       //设置守护线程,就是主线程结束后,守护线程不再执行下去
       td1.setDaemon(true);
       td2.setDaemon(true);

       td1.start();
       td2.start();
       for (int i = 0; i <10 ; i++) {
           System.out.println(Thread.currentThread().getName()+":"+i);
       }
   }
}

5、线程生命周期

6、多线程的实现方式2

方式二:实现Runnable接口

1. 定义一个类MyRunnable实现Runnable接口

2. 在MyRunnable中重写run()方法

3. 创建MyRunnable类的对象

4. 创建Thread类的对象,把MyRunnable对象作为构造方法的参数

5. 启动线程

public class MyRunnable implements Runnable{
   @Override
   public void run() {
       for (int i = 0; i < 10; i++) {
           //实现的Runnable接口,就必须要当拿到当前线程,再去获取名字,
           //这里不能直接使用getName()
           System.out.println(Thread.currentThread().getName()+":"+i);
       }
   }
}

public class MyRunnableDemo1 {
   public static void main(String[] args) {
       MyRunnable mr = new MyRunnable();
       //把MyRunnable的构造方法对象作为参数,创建2个线程
       Thread t1 = new Thread(mr);
       Thread t2 = new Thread(mr);
       //实现Runnable接口给线程取名字
       Thread t3 = new Thread(mr,"beijing");
       Thread t4 = new Thread(mr,"hangzhou");
       t1.start();
       t2.start();
       t3.start();
       t4.start();
   }
}

实现Runnable接口方式的优点:

1、 避免java单继承的局限性

2、 适合多个相同程序的代码去处理同一个资源的情况,把线程和程序的代码、数据有效分离,较好的体现了面向对象的设计思想

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

蜀州凯哥

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值