一、进程与线程的定义

进程:正在内存中执行的应用程序。

线程:是进程的一个执行单元。负责进程中程序的执行。一个进程中允许有多条线程,称之为多线程,如果只有一条线程,称之为单线程。一个进程至少必须有一条线程。

二、多线程的认识

【线程认识误区】

多线程并没有真正提高运行速度,在同一时刻只有一条线程在执行,只是因为线程切换的太快,产生同时执行的假象。所以尽管叫做多线程,但某一时刻仍然是单线程在工作。

【Java中的线程方式】

抢占式调度:线程具有优先级。理论上会先执行优先级高的线程。如果线程的优先级相同,那么会随机执行一条线程(线程的随机性)。对于CPU的一个核而言,同时只能有一条线程在执行。但是线程在核上进行着高速切换,所以感觉是同时在执行。

【线程的优点】

1.提高用户的体验。

2.提高了CPU的利用率。

线程的执行需要和计算机硬件交互。当线程和计算机硬件交互时,CPU会暂时的空置。所以多线程就能够提高CPU的利用率。

一条线程不会占据整个cpu的资源。

三、多线程的实现

【方式一】继承Thread类

步骤:

  1. 定义一个类继承自Thread
  2. 在子类中重写run方法,将需要被新线程执行的代码放入run方法
  3. 创建子类对象,调用start方法开启线程。
public class ThreadDemo {
	public static void main(String[] args) {
		SubThread sub = new SubThread();
		//调用start方法,开启线程
		sub.start();
		for (int i = 0; i < 100; i++) {
			System.out.println("主方法线程执行 "+ i + " 次");
		}
	}
}

/**
 * 自定义线程测试,继承Thread类
 */
class SubThread extends Thread{
	//重写run方法
	public void run() {
		for (int i = 0; i < 100; i++) {
			System.out.println("自定义线程执行 "+ i + " 次");
		}
	}
}

【方式二】实现Runnable接口

步骤:

  1. 定义类实现Runnable接口
  2. 实现接口中的run方法
  3. 创建实现类的对象
  4. 创建Thread对象,并且将实现类对象通过Thread的构造方法传入
  5. 调用start方法,开启新的线程
public class RunnableDemo {
	public static void main(String[] args) {
        //创建Thread对象,并将实现Runnable接口的类传入到Thread对象中
		Thread t = new Thread(new SubRun());
		t.start();
		for (int i = 0; i < 100; i++) {
			System.out.println("主方法线程执行 "+ i + " 次");
		}
	}
}

/**
定义类实现Runnable接口
实现接口中的run方法
*/
class SubRun implements Runnable{

	@Override
	public void run() {
		for (int i = 0; i < 100; i++) {
			System.out.println("自定义线程执行 "+ i + " 次");
		}
	}
	
}

 

 

补充:

【1】线程中run方法和start方法的区别?

run:并没有真正的开启新的线程,只是在原来线程中存放执行方法的代码

start:开启新的线程去执行run方法中的代码。

【2】线程的运行结果是不唯一的,谁先抢到资源,谁先运行