多线程的概念
进程是操作系统中进行保护和资源分配的基本单位,操作系统分配资源以进程为基本单位。而线程是进程的组成部分,它代表了一条顺序的执行流。
一个进程中是可以有多个线程的,
简而言之:一个程序运行后至少有一个进程,一个进程中可以包含多个线程
系统中的进程线程模型是这样的:
创建并启动一个线程
创建一个线程基本上有两种方式,一是通过传入 Runnable 实现类,二是直接重写 Thread 类的 run 方法。
1、自定义 Runnable 实现
1 public class MyRunnable implements Runnable { 2 public void run() { 3 for (int i = 0; i < 100; i++) {
System.out.println(Thread.currentThread().getName()+":"+i); 4 } 5 } 6 }
public static void main(String[] args) { //创建线程任务对象 MyRunnable mr=new MyRunnable(); //创建线程对象(并传递线程任务) Thread t=new Thread(mr); Thread t1=new Thread(mr); //开启线程 t.start(); t1.start(); //描述main执行的任务 for (int i = 0; i < 100; i++) { System.out.println(Thread.currentThread().getName()+":"+i); } }
运行结果:
其实 Thread 这个类也是继承 Runnable 接口的,并且提供了默认的 run 方法实现
2、继承 Thread 类
继承了Thread类的子类就是一个线程主体类。我们知道主线程入口是main()方法,那么其他也一样需要有自己的入口方法才能启动,其他线程的入口方法是start()和run()。
既然线程启动时会去调用 run 方法,那么我们只要重写 Thread 类的 run 方法也是可以定义出我们的线程类的。
1 public class MyThread extends Thread{ 2 //run是用来描述线程任务的 3 public void run() { 5 for (int i = 0; i < 100; i++) { 6 System.out.println(getName()+":"+i); 7 } 8 } 9 }
1 //创建线程对象 2 MyThread mt=new MyThread(); 3 //开启线程 4 mt.start(); 5 //描述main执行的代码 6 for (int i = 0; i < 100; i++) { System.out.println(Thread.currentThread().getName()+":"+i); 7 } 8 }
效果是一样的。
当使用start()方法启动线程的时候会进行cpu资源的调度,为每个线程分配cpu资源,或者更确切的说是每个线程抢占cpu资源,谁先抢到资源就先执行谁。
start()方法和run()方法的区别?
run(): 只是Java类的一个普通方法,不能实现cpu资源的调度,不能真正的启动一个线程
start(): 会启动一个线程,会在该方法中调用一个叫做start0()的方法进行cpu资源的调度,之后再去调用run()方法。
多线程内存图: