多线程
在计算机中为了提高内存和资源的利用率,引入了并发编程的思想;多进程和多线程都能实现并发编程,但是多线程相对于多进程更“轻量”,(多线程和多线程的关系和区别),所以这篇博客将着重讲解一下多线程相关的知识。
创建多线程
创建一个多线程
在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");
}
}
这里有两个线程,分别是主线程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的资源哪个线程就会先执行(由操作系统内核来决定),在应用程序层面我们无法得知,所以执行顺序是随机的。