多线程——多线程的创建方式、常用成员方法

目录

一、什么是多线程?

线程与进程

进程与线程区别:

并发与并行 

 二、多线程的创建方式(三种方式)

第一种:继承Thread类方式创建

第二种:实现Runnable接口的方式创建

第三种:利用Callable接口和Future方式创建

三、线程中常见的成员方法

1.获取线程名称、设置线程名、获取当前线程对象与休眠指定线程:

2.设置线程优先级与获取线程优先级: 

3.设置守护线程:守护线程会在其他线程执行完毕后延迟结束。 

4.出让线程/礼让线程 

5.插入线程/插队线程 :把指定线程插到当前线程之前执行


一、什么是多线程?

        多线程可以划分为“多”和“线程”,那么什么是线程呢?

线程与进程

        说起多线程,那么就不得不说什么是线程,而说起线程,又不得不说什么是进程。

  • 进程:是指一个内存中运行的应用程序(一组指令的有序集合),当一个程序被加载到内存中之后就变成了进程(进程=程序+执行)。每个进程都有一个独立的地址空间,进程也是程序的一次执行过程,是系统运行程序和操作系统分配资源的基本单位;系统运行一个程序即是一个进程从创建、运行到消亡的过程。进程的三种状态:

        1.阻塞态:等待某个事件的完成
        2.就绪态:等待系统分配CPU以便运行
        3.执行态:占用CPU正在运行

多线程——多线程的创建方式、常用成员方法_第1张图片

 

  • 线程:线程是进程中的一个执行单元,是进程的一个实体,是CPU调度和分派的基本单位。负责当前进程中程序的执行,与同属进程的其他线程共享进程拥有的全部资源。一个进程中至少有一个线程,一个进程中是可以有多个线程的,这个应用程序也可以称之为多线程程序。

进程与线程区别:

  • 进程是cpu资源分配的最小单位,线程是cpu调度的最小单位。
  • 一个程序至少有一个进程,一个进程至少有一个线程。线程依赖于进程才能运行
  • 线程本身拥有很少资源(线程标识符、程序计数器、一组寄存器的值、堆栈),与同属进程的其他线程共享进程拥有的资源(代码段、数据段、打开的文件、I/O设备等)。
  • 线程开销小,但一个线程死掉等于整个进程死掉,不利于资源管理和保护。而进程正好相反,开销大,但相对线程安全。 

并发与并行 

  • 并发:同一时刻,多个指令在单个CPU上交替执行。
  • 并行:同一时刻,多个指令在多个CPU上同时执行。

来个比喻:并发是一个人同时吃三个馒头,而并行是三个人同时吃三个馒头。

总结:

多线程——多线程的创建方式、常用成员方法_第2张图片

 二、多线程的创建方式(三种方式)

第一种:继承Thread类方式创建

 1.自己定义一个类,继承Thread
 2.重写run方法
 3.创建子类对象,启动线程
public class MyThread extends Thread{
    @Override
    public void run() {
        //线程要执行的代码
        for (int i = 0; i < 100; i++) {
            //Thread.currentThread()获取当前线程对象
            System.out.println(Thread.currentThread().getName()+"helloThread!");
        }
    }
}

public class threadcase1 {
    public static void main(String[] args) {
        /**
         * 多线程第一种启动方式
         * 1.自己定义一个类,继承Thread
         * 2.重写run方法
         * 3.创建子类对象,启动线程
         */
        //创建线程
        MyThread t1=new MyThread();
        MyThread t2=new MyThread();
        //为线程起名字
        t1.setName("线程1");
        t2.setName("线程2");

        //启动线程
        t1.start();
        t2.start();
        //并发执行,交替


    }
}

第二种:实现Runnable接口的方式创建

 1.自己定义一个类实现Runnable接口
 2.重写run方法
 3.创建自己类对象,
 4.创建Thread类对象并开启线程
public class MtRunnable implements Runnable{
    @Override
    public void run() {
        //线程要执行的代码
        for (int i = 0; i < 100; i++) {
            System.out.println(Thread.currentThread().getName()+"_"+"hello Runnable");
        }
    }
}

public class ThreadDemo {
    /**
     * 多线程第二种启动方式
     * 1.自己定义一个类实现Runnable接口
     * 2.重写run方法
     * 3.创建自己类对象,
     * 4.创建Thread类对象并开启线程
     */
    public static void main(String[] args) throws InterruptedException {
        //创建自己类对象
        //表示多线程要执行的任务
        MtRunnable mr=new MtRunnable();
        //创建线程对象
        Thread t1=new Thread(mr);
        Thread t2=new Thread(mr);
        //给线程设置名字
        t1.setName("01");
        t2.setName("02");
        //开启线程
        t1.start();
        t2.start();
        //并发,交替执行

    }
}

第三种:利用Callable接口和Future方式创建

 1.创建一个MyCallable类实现Callable接口
 2.重写call方法(有返回值,表示多线程运行的结果)
 3.创建MyCallable类对象(表示多线程要执行的任务)
 4.创建Future接口的实现类FutureTask的对象(用来管理多线程运行的结果)
 5.创建Thread类的对象,并启动(表示线程)
public class MyCallable implements Callable {
    @Override
    public String call() throws Exception {
        System.out.println(Thread.currentThread().getName());
        return "hello callable!";
    }
}

public class ThreadDemo {
    public static void main(String[] args) throws ExecutionException, InterruptedException {
        /**
         * 多线程第三种实现方式
         * 特点:可以获取多线程运行结果
         * 1.创建一个MyCallable类实现Callable接口
         * 2.重写call方法(有返回值,表示多线程运行的结果)
         *
         * 3.创建MyCallable类对象(表示多线程要执行的任务)
         * 4.创建Future接口的实现类FutureTask的对象(用来管理多线程运行的结果)
         * 5.创建Thread类的对象,并启动(表示线程)
         */
        //创建MyCallable类对象(表示多线程要执行的任务)
        MyCallable my=new MyCallable();
        //用futureTask去管理多线程运行的结果
        FutureTask futureTask=new FutureTask<>(my);
        //创建Thread类的对象,并启动(表示线程)
        new Thread(futureTask).start();
        //获取多线程运行的结果并打印
        String result = futureTask.get();
        System.out.println(result);

    }
}

三、线程中常见的成员方法

多线程——多线程的创建方式、常用成员方法_第3张图片

 代码演示:

1.获取线程名称、设置线程名、获取当前线程对象与休眠指定线程:

public class MyThread extends Thread {

    public MyThread() {
    }

    public MyThread( String name) {
        super(name);
    }


    @Override
    public void run() {
        for (int i = 0; i < 100; i++) {
            System.out.println(getName()+"@"+i);
        }
    }
}

public class ThreadDemo {
    public static void main(String[] args) throws InterruptedException {
        /*
        1 setName(String name)
            如果没有给线程设置名字,线程默认名字格式:Thread-X(X为序号,从0开始)
            设置名称:1.setName(),2.构造方法也可以为线程起名
        2 currentThread()获取当前线程对象
            JVM启动后,会自动启动多条线程
            其中有一条线程叫main线程,调用main方法并执行里面的代码
            我们之前写的所有代码,都是运行在main线程中
        3 sleep(Long time)让线程休眠指定时间,单位为毫秒
            哪条线程执行到这个方法,哪条线程就会在这里停留指定时间
            方法的参数:睡眠时间,单位:毫秒
            1s=1000ms
            当时间到了之后,线程会自动醒来,执行下面其他代码
         */
        //1.创建线程对象
        MyThread t1=new MyThread("线程1");
        MyThread t2=new MyThread("线程2");

        //2.开启线程
        t1.start();
        //Thread.sleep(1000);
        t2.start();


    }
}

2.设置线程优先级与获取线程优先级: 

public class MyRunnable implements Runnable {
    @Override
    public void run() {
        for (int i = 0; i < 100; i++) {
            System.out.println(Thread.currentThread().getName()+"_"+i);
        }
    }
}

public class ThreadMethod {
    public static void main(String[] args) {
        /*
        * setPriority(int newPriority);设置线程优先级
        *   优先级从1到10,优先级越高抢占cpu执行权概率越大
        *   优先级默认为5
        * final int getPriority();获取线程优先级
        * */
        //创建线程要执行的任务
        MyRunnable mr=new MyRunnable();
        //创建线程对象,执行任务
        Thread t1=new Thread(mr,"线程1");
        Thread t2=new Thread(mr,"线程2");

        //查看线程优先级 5
        System.out.println(t1.getPriority());
        System.out.println(t2.getPriority());

        t1.setPriority(1);
        t2.setPriority(10);

        t1.start();
        t2.start();
    }
}

3.设置守护线程:守护线程会在其他线程执行完毕后延迟结束。 

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


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

public class ThreadDemo {
    public static void main(String[] args) {
        /**
         * final void setDemo(boolean on) 设置为守护线程
         *      当其他的非守护线程执行完毕后,守护线程会陆续草草收尾(不会马上结束)
         * 通俗:
         *      女神结婚了,备胎没有存在的必要了
         * 应用场景:
         *      QQ聊天时,聊天窗口会占据一个线程,文件传输也会有一个线程
         *      当文件正在传输,聊天窗口关闭,文件传输也会停止
         */
        MyThread t1=new MyThread();
        DaemonThread t2=new DaemonThread();

        t1.setName("女神");
        t2.setName("备胎");

        //设置守护线程(备胎线程)
        t2.setDaemon(true);
        t1.start();
        t2.start();
    }
}

多线程——多线程的创建方式、常用成员方法_第4张图片

 

4.出让线程/礼让线程 

public class MyThread extends Thread {
    @Override
    public void run() {
        for (int i = 0; i < 100; i++) {

            System.out.println(getName()+"@"+i);
            //表示让出当先cpu的执行权
            Thread.yield();
        }
    }
}

public class ThreadDemo {
    public static void main(String[] args) {
        /**
         * public static void yield() 出让线程/礼让线程
         * 当线程1抢到cpu执行权后让出执行权给其他线程
         * 尽可能让线程的执行更加均匀
         */

        MyThread t1=new MyThread();
        MyThread t2=new MyThread();

        t1.setName("线程1");
        t2.setName("线程2");

        t1.start();
        t2.start();
    }
}

5.插入线程/插队线程 :把指定线程插到当前线程之前执行

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

public class ThreadDemo {
    /**
     * public final void join() 插入线程/插队线程
     *
     */
    public static void main(String[] args) throws InterruptedException {
        myThread t=new myThread();
        t.setName("土豆");
        t.start();
        //把土豆线程插入到当前线程之前 当前线程:main线程
        t.join();
        //执行main线程中
        for (int i = 0; i < 10; i++) {
            System.out.println("main线程"+i);
        }
    }

}

多线程——多线程的创建方式、常用成员方法_第5张图片

 

 

你可能感兴趣的:(java基础,java,开发语言)