java中,我们操作的都是对象,线程也不例外。
我们操作的线程也是对象,对象要有类,线程就是一个类。Thread
Thread:线
线程在java中到底是什么?
java中代码是顺序执行的,这个是不能改变的事实。
为什么是顺序执行的呢?因为栈。
方法在栈中执行,方法执行的时候要压栈弹栈。栈结构就是First in last out
这就是自上而下顺序执行的原理所在。
如何做到并发呢?
开辟另外的栈。
这就是多线程的原理。多线程的本质是多个栈内存空间。
每开一个线程,实际是在JVM栈内存空间中开辟了一个新的栈内存空间。
main方法所在的线程叫做主线程,main方法是所有程序的入口
入口只有一个。也就是说主线程只有一个。
比如:
大学生活,是一个程序,该程序主要功能是学习。这个程序中还有其他的功能比如锻炼、打游戏、谈恋爱、参加社团、学生会等等。
学习是主线,这要占用一定的时间,时间我们就可以看成是程序中的栈。其他的功能都是并发在做,因为一个时间点只能做一件事,所以是并发。学习就是主线程,其他的就是其他的线程。他们占用不同的时间,也就是说在不同的栈中。
4 操作多线程
方式一:一个类继承Thread类,重写run方法
package com.tj.threadTest;/**
* @program: Study
* @description:
* @author: tianjie
* @create: 2021-02-19 10:59
*/publicclassThreadTest03extendsThread{privateint num;publicThreadTest03(){}publicThreadTest03(int num){this.num = num;}@Overridepublicvoidrun(){for(int i =0; i <1000; i++){
System.out.println("线程 --> i = "+ i);}}publicintgetNum(){return num;}publicvoidsetNum(int num){this.num = num;}@Overridepublic String toString(){return"ThreadTest03{"+"num="+ num +'}';}}
开启线程:
new 对象,然后调用Thread的start()方法。线程就会被开启。
记住不是调用run方法,run方法不需要手动调用,是依靠start方法来开启线程
然后,JVM自动调用run方法。
publicclassClient{publicstaticvoidmain(String[] args){
Thread t =newThreadTest03(10);// 创建一个线程对象
t.start();// 启动线程// 1. 并没有调用run方法,为什么"线程 --> i = "会被打印,run为什么会被执行for(int i =0; i <1000; i++){
System.out.println("main ---> i = "+ i);}// 2. 为什么会在某些时段出现main和线程交替打印的结果// 3. 上来就打印main,这是为什么?// 4. 程序每次执行的结果都不一样}}// 开启线程不能直接调用run方法,run方法不是手动调用的,是JVM自动调用的// 开启线程要调用Thread类的start方法。
为什么是这样?
第二种方式:
第一种方式有什么缺陷?
class A extends Thread {}//A类的资源要被很多线程访问
使用继承的方式就是最大的缺陷。因为java只能单继承,不能多继承。一旦继承了
Thread类,A类无法继承其他类。
class Dog extends Animal{}
Dog类要并发,extends Thread,这时候还能做吗?
这种缺陷怎么弥补?
Thread类实现了Runnable接口,那么我们可以避开Thread类,直接实现Runnable接口
Runnable接口没有start方法,它是函数式接口,只有run方法
如何启动线程?启动线程只能是start方法。没有第二条路。记住!
Thread(Runnable target) 这是Thread的构造法方法,它可以放一个
Runnable的实例,Runnable是一个接口,没有实例,只能放Runnable的实现类的实例
Thread(dog)
publicclassDogimplementsRunnable{@Overridepublicvoidrun(){for(int i =0; i <1000; i++){
System.out.println("dog --->"+ i);}}}publicclassDogClient{publicstaticvoidmain(String[] args){
Dog dog =newDog();// Runnable接口没有start方法,它是函数式接口,只有run方法// 如何启动线程?
Thread t =newThread(dog);
t.start();// 借助Thread类来启动线程,因为start方法只有Thread类中有for(int i =0; i <100; i++){
System.out.println("main --> "+ i);}}}