实训24 2018.5.1

多线程

线程:

​ 线程是进程中的一个执行单元,负责当前进程中程序的执行,一个进程中至少有一个线程。一个进程中是可以有多个线程的,这个应用程序也可以称之为多线程程序。简而言之:一个程序运行后至少有一个进程,一个进程中可以包含多个线程。

​ 多线程就是一个程序中有多个线程在同时执行。

java中的线程:

​ 在cmd(或powershell)输入java classname后,启动JVM,并加载对应的class文件。虚拟机会从main方法开始执行程序代码,直至把main方法的代码执行结束这个执行路径(线程)在java中被称为主线程(main线程——该线程的名字即为main)。

Thread类:

​ java.lang.Thread,实现了Runnable接口

​ 构造方法:

​ Thread() 分配新的Thread对象

​ Thread(String name) 分配新的Thread对象,将指定的name作为该线程名字

​ 常用方法:

扫描二维码关注公众号,回复: 96859 查看本文章

​ void start() 使该线程开始执行;Java虚拟机调用该线程的run()方法。

​ void run() 该线程要执行的操作。

​ static void sleep(long millis) 在指定的毫秒数内让当前正在执行的线程休眠(暂停执行)

创建新执行线程的两种方法:

​ 方法一:创建类继承Thread类,该子类应重写Thread类的run()方法(因为Thread的run()的方法体为空)。将类声明为Thread的子类,通过该子类创建对象,使用start()方法开启线程。(start()会调用run()方法)

//Demo.java

public class Demo01 {
    public static void main(String[] args) {
        //创建自定义线程对象
        MyThread mt = new MyThread("新的线程!");
        //开启新线程
        mt.start();
        //在主方法中执行for循环
        for (int i = 0; i < 10; i++) {
            System.out.println("main线程!"+i);
        }
    }
}

class MyThread extends Thread {
    //定义指定线程名称的构造方法
    public MyThread(String name) {
        //调用父类的String参数的构造方法,指定线程的名称
        super(name);
    }
    /**
     * 重写run方法,完成该线程执行的逻辑
     */
    @Override
    public void run() {
        for (int i = 0; i < 10; i++) {
            System.out.println(getName()+":正在执行!"+i);
        }
    }
}

​ 注:调用该对象的run方法可以执行,但是并不会开启线程,即只是想普通类一样调用方法run()。而线程对象调用start时开启线程,并让JVM调用run方法在开启的线程中执行。

//ThreadDemo.java

class MyThread extends Thread {  //继承Thread
    MyThread(String name){
        super(name);
    }
    //复写其中的run方法
    public void run(){
        for (int i=1;i<=20 ;i++ ){
                System.out.println(Thread.currentThread().getName()+",i="+i);
        }
    }
}

public class ThreadDemo {
    public static void main(String[] args)  {
        //创建两个线程任务
        MyThread d = new MyThread();
        MyThread d2 = new MyThread();
        d.run();//没有开启新线程, 在主线程调用run方法
        d2.start();//开启一个新线程,新线程调用run方法
    }
}

​ 注:如何获取线程名字?Thread类中有如下方法:

​ static Thread currentThread() 返回对当前正在执行的线程对象的引用。

​ String getName() 返回该线程的名称。

​ 由于currentThread()是静态方法,所以直接使用Thread.currentThrea().getName()获取当前对象的名字。

​ 方法二:创建类实现Runnable接口,实现run()方法。声明该类并创建对象,传入到Thread类(或其子类)的构造方法中,使用start()开启线程。

//Demo02.java

class Demo02 {
    public static void main(String[] args) {
        //创建线程执行目标类对象
        Runnable runn = new MyRunnable();
        //将Runnable接口的子类对象作为参数传递给Thread类的构造函数
        Thread thread = new Thread(runn);
        Thread thread2 = new Thread(runn);
        //开启线程
        thread.start();
        thread2.start();
        for (int i = 0; i < 10; i++) {
            System.out.println("main线程:正在执行!"+i);
        }
    }
}

public class MyRunnable implements Runnable{

    //定义线程要执行的run方法逻辑
    @Override
    public void run() {
        
        for (int i = 0; i < 10; i++) {
            System.out.println("我的线程:正在执行!"+i);
        }
    }
}

Thread类中有构造方法用于接收Runnable的实现类的对象:

​ Thread(Runnable target) 分配新的Thread对象,以便将target作为其运行对象

​ Thread(Runnable target, String name) 分配新的Thread对象,以便将target作为其运行对象,将制定的name作为其名称。

​ 注:为什么需要定一个类去实现Runnable接口呢?继承Thread类和实现Runnable接口有啥区别呢?实现Runnable接口,避免了继承Thread类的单继承局限性。覆盖Runnable接口中的run方法,将线程任务代码定义到run方法中。创建Thread类的对象,只有创建Thread类的对象才可以创建线程。线程任务已被封装到Runnable接口的run方法中,而这个run方法所属于Runnable接口的子类对象,所以将这个子类对象作为参数传递给Thread的构造函数,这样,线程对象创建时就可以明确要运行的线程的任务。

猜你喜欢

转载自www.cnblogs.com/goxxiv/p/8977774.html