多线程继承Thread类和实现Runnable接口

进程和线程的区别

​ 进程:应用程序的执行实例,有独立的内存空间和系统资源

​ 线程:CPU调度和分派的基本单位,进程中执行运算的最小单位,可完成一个独立的顺序控制流程

进程和线程的关系

(1)一个线程只能属于一个进程,而一个进程可以有多个线程,但至少有一个线程。线程是操作系统可识别的最小执行和调度单位。

(2)资源分配给进程,同一进程的所有线程共享该进程的所有资源。 同一进程中的多个线程共享代码段(代码和常量),数据段(全局变量和静态变量),扩展段(堆存储)。但是每个线程拥有自己的栈段,栈段又叫运行时段,用来存放所有局部变量和临时变量。

(3)处理机分给线程,即真正在处理机上运行的是线程。

(4)线程在执行过程中,需要协作同步。不同进程的线程间要利用消息通信的办法实现同步。

继承Thread类 创建线程

步骤: 1,定义类继承Thread

​ 2,复写Thread类中的run方法

​ 3,调用线程的start方法,该方法有两个作用:启动线程和调用run方法

run()方法:在本线程内调用该对象的run()方法,可以重复多次调用,

start()方法:启动一个线程,调用该对象的run()方法,不能多次启动一个线程。

start()是告诉线程准备完毕,可以运行了,然后run()就是运行状态方法。

class Demo extends Thread{  
    public void run(){ //复写Thread类中的run方法 
        System.out.println("Demo run");  
    }  
} 
class ThreadDemo{  
    public static void main(String[] args){  
        Demo d = new Demo();//创建好一个线程  
           d.start();  //开启线程并执行该线程的run方法 
           d.run();
       /* 如果我们没有开启线程(没有调用线程的start()方法)而是在应用代码中直接调用run()方法,那么这个线程的run()方法其实运行在当前线程(即run()方法的调用方所在的线程)之中,而不是运行在其自身的线程中*/
        for(int x=0;x<60;x++)  
            System.out.println("Hello "+x);  
    }  
}

运行结果每一次都不同,因为多个线程都在获取CPU的执行权 CPU执行到谁,谁就运行,明确一点,在某一时刻只能有一个程序 在运行(多核除外) CPU在做着快速的切换,以达到看上去是同时运行的效果。 可以把多线程的运行行为是在互相抢夺CPU执行权 ,这就是多线程的一个特性:随机性,谁抢到谁执行,运行时间由CPU控制。
Runnable 接口应该由那些打算通过某一线程执行其实例的类来实现。类必须定一个称为run的无参方法

实现Runnable接口创建多线程的优点

1、避免单继承的局限性

2.可以避免由于Java的单继承性带来的局限性

3.增强了程序的健壮性,代码能够被多个线程共享,代码与数据是独立的。

一个类只能继承一个类,类继承了Thread类就不能够继承其他的类了

实现Runnable接口,还可以继承其他的类,实现其他的接口

package TestDemo;
class MyThread implements Runnable{
    private String name;
    public MyThread(String name){
        this.name=name;
    }
    public void run() {
        for (int i = 0; i < 200; i++) {
            System.out.println(this.name+i);
        }
    }
}
public class TestDemo{
    public static void main(String[] args) {
        MyThread thread1=new MyThread("Thread1");
        MyThread thread2=new MyThread("Thread2");
        new Thread(thread1).start();
        new Thread(thread2).start();
    }
}

5 种线程状态:
1. 新建状态(New): 线程对象被创建后,就进入了新建状态。例如,Thread thread = new Thread()。

2. 就绪状态(Runnable): 也被称为“可执行状态”。线程对象被创建后,其它线程调用了该对象的start()方法,从而来启动该线程。例如,thread.start()。处于就绪状态的线程,随时可能被CPU调度执行。

3. 运行状态(Running): 线程获取CPU权限进行执行。需要注意的是,线程只能从就绪状态进入到运行状态。

4. 阻塞状态(Blocked): 阻塞状态是线程因为某种原因放弃CPU使用权,暂时停止运行。直到线程进入就绪状态,才有机会转到运行状态。阻塞的情况分三种:

(01) 等待阻塞 – 通过调用线程的wait()方法,让线程等待某工作的完成。
(02) 同步阻塞 – 线程在获取synchronized同步锁失败(因为锁被其它线程所占用),它会进入同步阻塞状态。
(03) 其他阻塞 – 通过调用线程的sleep()或join()或发出了I/O请求时,线程会进入到阻塞状态。当sleep()状态超时、join()等待线程终止或者超时、或者I/O处理完毕时,线程重新转入就绪状态。

5. 死亡状态(Dead): 线程执行完了或者因异常退出了run()方法,该线程结束生命周期。

猜你喜欢

转载自blog.csdn.net/Longsoul/article/details/106887650