多线程

在计算机中为了提高内存和资源的利用率,引入了并发编程的思想;多进程和多线程都能实现并发编程,但是多线程相对于多进程更“轻量”,(多线程和多线程的关系和区别),所以这篇博客将着重讲解一下多线程相关的知识。

创建多线程

创建一个多线程

在Java中,创建线程通常使用Thread类来实例化对象,因为该类封装了很多可以调用操作系统内核的API
代码如下:

class MyThread extends Thread {
    @Override
    public void run() {
        System.out.println("hello Thread");
    }
}
public class ThreadDemo {
    public static void main(String[] args) {
        Thread t = new MyThread();
        t.start();

        System.out.println("hello main");
    }
}

Java lambda 创建多线程 java如何创建多线程_面试

这里有两个线程,分别是主线程main和我们创建的新线程(主线程调用新线程),第一行代码实例化了一个t对象(注意这里并没有创建线程),t调用start方法之后在操作系统内核创建了一个PCB,PCB通过调用CPU来执行相关的指令。

run()和start()的区别

在main方法中我们可以看出,为了执行MyThread类中的run方法时并不是让t直接调用run方法的,而是调用start方法去执行run方法,这是为什么呢?
run方法:主要描述的该线程所要执行的任务,并不会创建线程
start方法:真正实现了新线程的创建,在操作系统内核创建了一个PCB,PCB通过调用CPU来执行相关的指令
换一个角度想一下:如果把找个的t.start()改成了t.run()的话,那么就相当于在main方法中去调用MyThread类中的方法,这里就只有一个主线程main了,不能实现多线程的操作了

创建线程的5中方法

法一:继承Thread重写run

class MyThread extends Thread {
    @Override
    public void run() {
        System.out.println("hello Thread");
    }
}
public class ThreadDemo {
    public static void main(String[] args) {
        Thread t = new MyThread();
        t.start();

        System.out.println("hello main");
    }
}

法二:实现Runnable接口

class MyRunnable implements Runnable {

    @Override
    public void run() {
        System.out.println("hello Thread");
    }
}
public class ThreadDemo {
    public static void main(String[] args) {
        Runnable runnable = new MyRunnable();
        Thread t = new Thread(runnable);
        t.start();
        
        System.out.println("hello main");
    }
}

法三:使用匿名内部类继承Thread

public class ThreadDemo {
    public static void main(String[] args) {
        Thread t = new Thread() {
            @Override
            public void run() {
                System.out.println("hello Thread");
            }
        };
        t.start();

        System.out.println("hello main");
    }
}

法四:使用匿名内部类实现Runnable

public class ThreadDemo {
    public static void main(String[] args) {
        Thread t = new Thread(new Runnable() {
            @Override
            public void run() {
                System.out.println("hello Thread");
            }
        });
        t.start();

        System.out.println("hello main");
    }
}

法五:使用Lambda表达式(最为简洁,推荐使用

public class ThreadDemo {
    public static void main(String[] args) {
        Thread t = new Thread(() -> {
            System.out.println("hello Thread");
        });
        t.start();

        System.out.println("hello main");
    }
}

多线程执行的顺序

上述展现了5种创建线程的方法,但是新线程和主线程main哪个会先执行呢?
线程在CPU上的调度是抢占式执行的,哪个线程先抢到CPU的资源哪个线程就会先执行(由操作系统内核来决定),在应用程序层面我们无法得知,所以执行顺序是随机的