Java中实现线程的两种方式
关于多线程的基本概述:
1、什么是进程?什么是线程?
进程是一个应用程序。
线程是一个进程中执行场景,执行单元。
一个进程可以启动多个线程。
进程与进程之间内存独立不共享。
2、在java语言中:
任意两个线程与线程之间,堆内存和方法区内存共享,因为堆内存和方法区只有一个。
但是栈内存独立,一个线程一个栈。栈内存有很多个。
假设有10个线程,会有10个栈空间,每个栈之间互不干扰,各自执行。
这就是多线程并发执行。
3、java中之所以有多线程机制,目的就是为了提高程序的效率。
思考:使用了多线程机制之后,main()方法结束后,是不是有可能程序也不会结束。
main()方法结束只是主线程结束,主栈空了,其他线程的栈可能还在压栈弹栈。
4、在java中实现线程有2种方法:
(1)第一种方法:编写一个类,直接继承java.lang.Thread,并重写run()方法。
怎么创建线程?直接new对象。
怎么启动线程?调用对象的start()方法。
public class MyThread extends Thread {
// 重写父类的run()方法
public void run() {
// 代码块
}
}
MyThread myThread = new MyThread();
myThread.start();
注意:start()方法调用时,启动一个分支线程,在JVM中开辟一个新的栈空间。
只有栈空间开出来了,start()方法在被调用的地方,瞬间出栈消失。
线程启动后,会自动调用run()方法,并且run()方法在分支栈的底部。
run()方法在分支栈底部,main()方法在主栈底部。
如果直接启动对象的run()方法呢?而不是通过start()去启动run()呢?
这样的话就不会去开辟新栈空间了,还是在当前栈中执行的run()方法。
测试代码:
public class Test01 {
public static void main(String[] args) {
// 这里是main()方法,属于主线程,对应一个主栈
// 创建分支线程对象
MyThread myThread = new MyThread();
// 启动分支线程,这行代码瞬间就结束了,因为它只起到开辟线程栈的功能
// 线程执行的时间跟这句代码没有关系
// 注意:方法体中的代码永远都是自上而下,逐行执行,这是亘古不变的
myThread.start();
// 如果是这种调用,只是普通的方法调用
// myThread.run();
// 这里的代码还是在主线程中
for (int i = 0; i < 100; i++) {
System.out.println("主线程---->" + i);
}
}
}
// 编写一个类,继承Thread,重写run()方法
class MyThread extends Thread {
@Override
public void run() {
for (int i = 0; i < 100; i++) {
System.out.println("分支线程---->" + i);
}
}
}
运行截图:
(2)实现线程的第二种方法:
编写一个类,实现java.lang.Runnable接口,实现接口中的run()方法。 再创建线程Thread对象。
怎么创建线程?直接new线程Thread对象,传一个类型为Runnable接口类型对象。
怎么启动线程?调用Thread对象的start()方法。
public class MyRun implements Runnable {
// 实现接口中的run()方法
public void run() {
// 代码块
}
}
Thread thread = new Thread(new MyRun());
thread.start();
注意:两种方式都能实现多线程,但第二种方式面向接口更常用。
因为一个类实现了接口,它还可以去继承其他的类,更灵活。
测试代码:
public class Test02 {
public static void main(String[] args) {
// 主线程main()方法的栈执行
// 创建可运行的参数对象
//MyRun myRun = new MyRun();
// 将可运行对象封装成线程对象
//Thread thread = new Thread(myRun);
// 以上两行代码可以合并
Thread thread = new Thread(new MyRun());
// 启动线程
thread.start();
// 也可以采用匿名内部类方式,直接new接口,这种方式不建议使用,代码不能复用
Thread thread1 = new Thread(new Runnable() {
@Override
public void run() {
for (int i = 0; i < 100; i++) {
System.out.println("分支2线程--->" + i);
}
}
});
thread1.start();
// 这是主线程中执行的代码
for (int i = 0; i < 100; i++) {
System.out.println("主线程--->" + i);
}
}
}
// 这个class还不是线程类,只是一个普通可运行的类
class MyRun implements Runnable {
@Override
public void run() {
for (int i = 0; i < 100; i++) {
System.out.println("分支1线程--->" + i);
}
}
}
运行截图:
还没有评论,来说两句吧...