java基础之多线程实现(一)

目录

一: 创建线程的第一种方式:继承Thread类(java.lang.Thread不需要导包)

  1:步骤

2:调用run()与调用start()的区别

3:获取和设置线程名字

4:线程调度(两种模型)

5: 获取和设置线程的优先级

6:线程控制

7:线程种类

二:例子

1:例子所用的实现Thread类的自定义类

2:设置获取名字以及设置获取优先级

3:休眠和加入

 4:礼让和后台线程

          5;中断线程


一: 创建线程的第一种方式:继承Thread类(java.lang.Thread不需要导包)

  1:步骤

  1、自定义一个子类MyThread1继承Thread类
   2、自定义类重写Thread类中的run()方法
   3、创建子类对象(每new一次就相当于创建一个线程)
   4、启动线程(不能多次启动,多次会报错java.lang.IllegalThreadStateException)

2:调用run()与调用start()的区别

run()的调用仅仅是封装了被线程执行的代码,但是直接调用的话是普通的方法调用

start()方法的调用,首先单独启动了一个线程,然后再由JVM去调用该线程的run()方法

3:获取和设置线程名字

通过构造方法给线程起名字:

Thread(String name) 分配一个新的 Thread对象。

通过方法给线程起名字:

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

void getName(String name) 得到线程名字

如何获取main方法所在的线程名称呢?

public static Thread currentThread()

4:线程调度(两种模型)

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

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

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

5: 获取和设置线程的优先级

public final int getPriority()返回此线程的优先级。

设置线程的优先级

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

参数newPriority的范围为1-10之间

注意:1、线程的默认优先级为5

2、线程优先级的范围是1-10(超出范围报错java.lang.IllegalArgumentException)

3、线程优先级高仅仅表示的是获取CPU时间片的几率会高一些,但是不是绝对一定会获取

6:线程控制

(1:线程休眠(在run方法里休眠)(用Thread调用)

public static void sleep(long millis)(毫秒)

(2:线程加入

public final void join()(在main方法)(用对象调用)

其他线程等待这个线程死亡(执行完)

注意事项:在线程设置为加入线程之前,先将该线程变为就绪状态,也就是调用start()方法

(3:线程礼让(在run方法)(直接用)

public static void yield()

暂停当前正在执行的线程对象,并执行其他线程

它的作用是为了让多个线程之间更加和谐一点,并不并不能一定保证多个线程一人一次执行

(4:后台线程(守护线程)(在main方法用对象调用)

public final void setDaemon(boolean on)

通过这个方法将该线程对象标记为守护线程或者非守护线程。

当运行的程序只有一个线程且是守护线程的时候,Java虚拟机退出

注意:将线程设置为守护线程这一步骤,必须在启动前设置。

(5:中断线程

public final void stop()(在main方法中用对象调用)

让正在运行的线程停止,run方法剩下的代码不会执 行,这个方法过时了,被弃用了,但是还能使用

public void interrupt()(在main方法中用对象调用)

中断正在运行的线程,被中断的线程将run方法执行完毕,并抛出异常 java.lang.InterruptedException: sleep interrupted

7:线程种类

  Java中有两类线程:用户线程、守护线程

        用户线程:我们在学习多线程之前所有程序代码,运行起来都是一个个的用户线程。

        守护线程:所谓的守护线程,指的就是程序运行的时候在后台提供了一种通用服务的线程。比如说
            垃圾回收线程,它就是一个称职的守护者,并且这种线程并不属于程序不可或缺的部分。所以
            非守护线程结束的时候,程序也就终止了,同时会杀死进程种所有的守护线程。
            反过来说,只要程序种存在非守护线程,程序就不会终止。

二:例子

1:例子所用的实现Thread类的自定义类

package day32;

public class MyThread extends Thread{//定义一个 MyThread类继承Thread
    @Override
    //重写run方法实现从1到10的输出并且输出线程名字
    public void run() {
        for(int i =0;i<=10;i++){
            System.out.println(Thread.currentThread().getName()+"**"+i);
        }
    }
}

2:设置获取名字以及设置获取优先级

package day32;

public class Thread1 {
    public static void main(String[] args) {
        //定义两个线程
        MyThread myThread = new MyThread();
        MyThread myThread1 = new MyThread();
        //设置和获取线程名线程名
        System.out.println(myThread.getName());
        System.out.println(myThread1.getName());
        System.out.println("=============================");
        myThread.setName("线程1");
        myThread1.setName("线程2");
        System.out.println(myThread.getName());
        System.out.println(myThread1.getName());
        System.out.println("=============================");
        //设置和获取线程优先级
        System.out.println(myThread.getPriority());
        System.out.println(myThread1.getPriority());
        System.out.println("=============================");
        myThread.setPriority(5);
        myThread1.setPriority(8);
        System.out.println(myThread.getPriority());
        System.out.println(myThread1.getPriority());


    }
}

 通过观察发现线程有默认的名字Thread-0和Thread-1有默认的优先级5

3:休眠和加入

package day32;

public class MyThread extends Thread{//定义一个 MyThread类继承Thread
    @Override
    //重写run方法实现从1到10的输出并且输出线程名字
    public void run() {
        //执行前休眠3秒钟
        try {
            Thread.sleep(3000);
            for(int i =0;i<=10;i++){
                System.out.println(Thread.currentThread().getName()+"**"+i);
            }
        } catch (InterruptedException e) {
            e.printStackTrace();
        }

    }
}
package day32;

public class Thread1 {
    public static void main(String[] args) {
        //定义两个线程
        MyThread myThread = new MyThread();
        MyThread myThread1 = new MyThread();
        //设置线程名字
        myThread.setName("线程1");
        myThread1.setName("线程2");
        //启动线程
        myThread.start();

        //将myThread加入
        try {
            myThread.join();
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        myThread1.start();

    }
}

 4:礼让和后台线程

package day32;

public class MyThread extends Thread{//定义一个 MyThread类继承Thread
    @Override
    //重写run方法实现从1到100的输出并且输出线程名字
    public void run() {
            for(int i =0;i<=100;i++){
                System.out.println(Thread.currentThread().getName()+"**"+i);
                yield();//礼让
            }

    }
}
package day32;

public class Thread1 {
    public static void main(String[] args) {
        //定义两个线程
        MyThread myThread = new MyThread();
        MyThread myThread1 = new MyThread();
        //设置线程名字
        myThread.setName("线程1");
        myThread1.setName("线程2");
        //将myThread设置为后台线程
        myThread.setDaemon(true);
        //启动线程
        myThread.start();
        myThread1.start();

    }
}

 当线程2执行结束后线程1没结束也关了

5;中断线程

package day32;

public class MyThread extends Thread{//定义一个 MyThread类继承Thread
    @Override
    //重写run方法实现从1到10的输出并且输出线程名字
    public void run() {
            for(int i =0;i<=10;i++){
                System.out.println(Thread.currentThread().getName()+"**"+i);
            }

    }
}
package day32;

public class Thread1 {
    public static void main(String[] args) {
        //定义两个线程
        MyThread myThread = new MyThread();
        MyThread myThread1 = new MyThread();
        //设置线程名字
        myThread.setName("线程1");
        myThread1.setName("线程2");
        //将myThread中断
        myThread.stop();
        //启动线程
         myThread1.start();
        myThread.start();
        

    }
}

package day32;

public class Thread1 {
    public static void main(String[] args) {
        //定义两个线程
        MyThread myThread = new MyThread();
        MyThread myThread1 = new MyThread();
        //设置线程名字
        myThread.setName("线程1");
        myThread1.setName("线程2");


       //启动线程
        myThread1.start();
        myThread.start();
        //将myThread中断
        myThread.interrupt();


    }
}

猜你喜欢

转载自blog.csdn.net/weixin_50691399/article/details/121131608