一、多线程
1.介绍
- 进程:正在运行的程序
- 线程:进程中的一个执行单元,一个程序至少有一个进程,每个进程至少有一个线程
2.程序运行原理
- 分时调度:所有线程轮流使用CPU,平均分配使用时间
- 抢占模式:优先让优先级高的线程使用CPU。如果优先级相同,那么会随机分配。Java使用的就是抢占式。
3.主线程
- 执行main方法的线程称为主线程
4.Thread类
- 构造函数
- 空参构造函数:Thread();
- String 参数构造函数:Thread(String threadName);
- 常用方法
- void start(); 线程开始,jvm调用该线程的run方法
- void run(); 该线程要执行的操作;主要线程的代码,比如100次循环打印
- static void sleep(); 静态方法,类名调用。线程休眠,暂停执行
5.创建线程
- 方式一:继承Thread类
- 定义一个线程类,例如MyTherad,继承Thread
- 重写MyTherad类的run()方法
- 创建线程对象,即MyTherad的对象
- 调用对象的start方法
- 代码展示:
public class MyThread extends Thread{
public MyThread()
{
}
/*
* 通过构造函数,确定线程的名字
*/
public MyThread(String name)
{
super(name);
}
/*
* (重写run方法)
* @see java.lang.Thread#run()
*/
public void run()
{
for (int i = 0; i < 10; i++) {
System.out.println(getName() + ": 正在执行" + i);
}
}
}
public class Demo1 {
public static void main(String[] args) {
MyThread myThread = new MyThread("Thread-0");
myThread.start();
for (int i = 0; i < 10; i++) {
System.out.println("main线程:正在执行:" + i);
}
}
}
- 创建线程方式二:实现Runnable接口
- 主要方法
- run(); //线程执行的代码块
- Thread(Runnable target); //构造线程时。可以传入runnable接口或者其子类
- Therad(Runnable target,String name); //以Runnable构造线程对象,以name为线程的名字
- 主要方法
-
- 创建步骤
- 定义类RunThread,实现Runnable接口
- 实现接口的run()方法
- 创建RunThread的对象
- 创建Thread类对象,创建的时候,构造函数参数中,传入RunThread的对象
- 执行Therad类的start方法,开启线程
- 创建步骤
-
- 代码展示
public class MyRunThread implements Runnable{
@Override
public void run() {
for (int j = 0; j < 10; j++) {
System.out.println("执行" + j);
}
}
}
public class Demo1 {
public static void main(String[] args) {
// MyThread myThread = new MyThread("Thread-0");
// myThread.start();
MyRunThread runTh = new MyRunThread();
Thread t = new Thread(runTh, "thread-0");
t.start();
for (int i = 0; i < 10; i++) {
System.out.println("main线程:正在执行:" + i);
}
}
}
- 两种创建方式的区别
- Runnable接口方式避免了单继承的局限性,所以较为常用
- 获取线程名称
- static Thread currentTherad(); //静态方法。返回当前正在执行的线程对象
- String getName(); //非静态方法。返回调用对象线程的名称
- Thread.currentThread().getName(); //获取任意线程的名称
二、线程池
1.概念
- 线程池其实就是一个容纳多个线程的容器,其中的线程可以反复的使用,省去了频繁创建线程对象的操作,无需反复创建线程而消耗过多的资源。
2.使用Runnable创建线程池
- 通常线程池是通过线程池工厂Executors类创建。
- Excuetors类:线程池创建工厂类
- public static ExcuetorService newFixedTheradPool(int nThreads); //参数为线程池中线程的个数,返回值为线程池对象
- ExcuetorsService类:线程池类
- Future<?> submit(Runnable task); //获取线程池中某一个线程对象,并执行;返回值用来记录线程任务执行完毕后产生的结果。
- 线程池创建步骤
- 创建线程池对象:Excuetors.newFixedTheradPool(5);
- 创建runnable对象:new Runnable();
- 关联runnable对象:submit(runnable);
- 关闭线程池
- 代码展示
//1.创建线程池工厂类
ExecutorService es = Executors.newFixedThreadPool(5);
//2.创建Runnable对象,注意使用runnable创建的线程对象是没有返回值的
Runnable task1 = new MyRunThread();
Runnable task2 = new MyRunThread();
Runnable task3 = new MyRunThread();
//给线程池中的线程关联runnable任务
Future<?> f1 = es.submit(task1);
Future<?> f2 = es.submit(task2);
Future<?> f3 = es.submit(task3);
//注意submit方法调用结束后,程序并不会终止,因为线程的关闭是由线程池控制的
//关闭线程池
es.shutdown();
for (int i = 0; i < 10; i++) {
System.out.println("main线程:正在执行:" + i);
}
3.使用Callable创建带返回值地线程池
- 与runnable接口相似,用来给线程池中的线程提供关联。其中call()方法,用来返回线程任务执行完毕后的结果。call方法会抛出异常。
- ExecutorService线程池类的构造方法中有一个带参数Callable的
- Future<T> submit(Callable<T> task); //将线程池中的线程与Callable进行关联。并执行Callable中的call()方法。
- 返回值Future用于记录线程任务执行完毕后产生的结果
- 创建步骤
- 创建线程池对象:Executors.newFixedThreadPool(int count);
- 创建Callable线程任务对象:
- 将Callable线程任务对象与线程池中的线程进行关联
- 关闭线程池
- 代码展示
//1.创建线程池对象
ExecutorService es = Executors.newFixedThreadPool(5);
//2.创建Callable线程任务接口
Callable <String> call = new Callable<String>() {
@Override
public String call() throws Exception {
for(int i = 0 ; i <10 ; i++)
{
System.out.println("第" + i + "次");
}
return "ssss";
}
};
//3.关联线程
es.submit(call);
es.submit(call);
Future<String> f = es.submit(call);
//4.打印返回值
System.out.println(f.get());
//5.关闭线程
es.shutdown();
//6.主线程打印循环
for (int i = 0; i < 10; i++) {
System.out.println("main线程:正在执行:" + i);
}
4.线程池练习:返回两个数相加的结果
public class TestCallableThread implements Callable<Integer>{
private int a;
private int b;
public TestCallableThread()
{
}
public TestCallableThread(int a,int b)
{
this.a = a;
this.b = b;
}
@Override
public Integer call() throws Exception {
return a+b;
}
}
public class Demo2 {
public static void main(String[] args) throws InterruptedException, ExecutionException {
//1.创建线程池
ExecutorService es = Executors.newFixedThreadPool(5);
//2.创建线程任务
Callable<Integer> call1 = new TestCallableThread(100, 200);
Callable<Integer> call2 = new TestCallableThread(200, 200);
Callable<Integer> call3 = new TestCallableThread(300, 200);
//3.关联
Future<Integer> f1 = es.submit(call1);
Future<Integer> f2 = es.submit(call2);
Future<Integer> f3 = es.submit(call3);
//4.打印结果
System.out.println("f1结果:" + f1.get());
System.out.println("f2结果:" + f2.get());
System.out.println("f3结果:" + f3.get());
//5.关闭线程池
es.shutdown();
}
}
全文完!