首先介绍进程与线程的基本概念
1.进程与线程
进程:正在运行的程序,是系统进行资源分配的基本单位。
线程:线程可以称为轻量级进程,它进程中的一条执行路径,也是CPU的基本调度单位。
一个进程由一个或多个线程组成,彼此间完成不同的工作。多个线程同时工作,称为多线程。
2.进程与线程的区别:
(1)进程是操作系统分配资源的基本单位,线程是CPU调度的基本单位。
(2)一个程序运行至少有一个进程
(3)一个进程可以包含多个线程,但至少有一个线程。
(4)进程间不能共享数据段地址,但同进程的线程之间可以。
3.线程的组成
(1)CPU时间片:操作系统会为每个线程分配执行时间
(2)运行数据:
堆内存:存储线程使用的对象,多个线程可以共享堆中对象。
栈内存:存储线程使用的局部变量,每个线程都拥有独立的栈。
(3)线程的逻辑代码
4.线程的特点
(1)线程抢占执行。
(2)并发执行,单核CPU中,是顺序执行(线程切换)。
5.创建线程的四种方式
(1)继承Thread类
(2)实现Runnable接口
(3)实现Callable接口
(4)使用线程池
1 package com.example.concurrency; 2 3 import java.util.concurrent.Callable; 4 import java.util.concurrent.ExecutionException; 5 import java.util.concurrent.Executor; 6 import java.util.concurrent.ExecutorService; 7 import java.util.concurrent.Executors; 8 import java.util.concurrent.Future; 9 import java.util.concurrent.FutureTask; 10 //第一种:继承Thread类 11 class MyThread extends Thread { 12 public void run() { 13 System.out.println("线程调用"); 14 } 15 } 16 17 //第二种,实现Runnable接口 18 class MyRunnable implements Runnable { 19 private Boolean tag = true; 20 21 @Override 22 public void run() { 23 // TODO Auto-generated method stub 24 int i = 0; 25 while (tag) { 26 System.out.println("线程调用:" + i++); 27 } 28 } 29 30 public void stop() { 31 this.tag = false; 32 } 33 } 34 35 //第三种:实现Callable接口 36 class MyCallable implements Callable<Integer> { 37 38 @Override 39 public Integer call() throws Exception { 40 // TODO Auto-generated method stub 41 System.out.println("线程调用,返回123"); 42 return 123; 43 } 44 45 } 46 47 //创建线程的四种方式 48 public class demo05 { 49 50 public static void main(String[] args) throws InterruptedException, ExecutionException { 51 // 方式一:继承Thread类 52 MyThread thread3 = new MyThread(); 53 thread3.start(); 54 55 // 方式二:实现Runnable接口 56 MyRunnable instance = new MyRunnable(); 57 Thread thread = new Thread(instance); 58 thread.start(); 59 60 // 方式三-实现Callable接口: 61 MyCallable mc = new MyCallable(); 62 FutureTask<Integer> ft = new FutureTask<Integer>(mc); 63 Thread thread2 = new Thread(ft); 64 thread2.start(); 65 66 // 方式四-使用线程池: 67 ExecutorService ser = Executors.newFixedThreadPool(1);// 线程池 68 Future<Integer> ft2 = ser.submit(mc);// 执行线程 69 Integer result = ft2.get();// 获取结果 70 ser.shutdown();// 关闭 71 } 72 }
5.1线程池使用的详细代码:
1 public class demo01 { 2 //线程池的使用 3 public static void main(String[] args) { 4 // 1创建线程池 5 6 // 1.1 创建固定数量的线程池 7 // ExecutorService eService = Executors.newFixedThreadPool(4); 8 // 1.2创建不固定数量的线程池,缓存线程池 9 ExecutorService eService = Executors.newCachedThreadPool(); 10 11 //1.3创建单线程的线程池 12 //Executors.newSingleThreadExecutor(); 13 14 //1.4创建调度线程池 15 //Executors.newScheduledThreadPool(4); 16 17 // 2.创建任务 18 Runnable runnable = new Runnable() { 19 private int ticket = 500; 20 21 @Override 22 public void run() { 23 for (int i = 500; i >= 0; i--) { 24 saleTicket(); 25 } 26 } 27 28 public synchronized void saleTicket() { 29 if (ticket > 0) { 30 ticket--; 31 System.out.println(Thread.currentThread().getName() + "卖了1张票,库存还有" + this.ticket + "张票"); 32 } 33 } 34 }; 35 36 // 3.启动线程池 37 for (int i = 0; i < 4; i++) { 38 eService.submit(runnable); 39 } 40 41 // 4.关闭线程池 42 eService.shutdown();// 等待线程执行完毕 43 // eService.shutdownNow();//不等待线程执行完毕,直接关闭 44 } 45 }
5.2使用Callable实现1-100的和
1 public class demo02 { 2 //功能需求:使用Callable实现1-100的和 3 public static void main(String[] args) { 4 //1.创建Callable对象 5 Callable<Integer> callable = new Callable<Integer>() { 6 @Override 7 public Integer call() throws Exception { 8 int sum = 0; 9 for(int i=1;i<=100;i++) { 10 sum += i; 11 } 12 return sum; 13 } 14 }; 15 16 //2.将Callable对象,转换成可运行的任务 17 FutureTask<Integer> task = new FutureTask<>(callable); 18 19 //3.将任务对象传递给Thread对象 20 Thread thread = new Thread(task); 21 22 //4.启动线程 23 thread.start(); 24 25 //5.获得结果 26 Integer result; 27 try { 28 result = task.get(); 29 System.out.println("计算结果为:"+result); 30 } catch (InterruptedException e) { 31 // TODO Auto-generated catch block 32 e.printStackTrace(); 33 } catch (ExecutionException e) { 34 // TODO Auto-generated catch block 35 e.printStackTrace(); 36 } 37 } 38 }
5.3使用线程池计算1-100的和
public class demo03 { //使用线程池,计算1-100的和 public static void main(String[] args) { //1.创建单线程的线程池 ExecutorService exectorService = Executors.newSingleThreadExecutor(); //2.创建Callable对象 Callable<Integer> callable = new Callable<Integer>() { @Override public Integer call() throws Exception { int sum = 0; for(int i=1;i<=100;i++) { sum += i; } return sum; } }; //3.将callable对象送给线程池 Future<Integer> future = exectorService.submit(callable); //4.获取计算结果 try { Integer result = future.get(); System.out.println("计算结果为:"+result); } catch (InterruptedException e) { // TODO Auto-generated catch block e.printStackTrace(); } catch (ExecutionException e) { // TODO Auto-generated catch block e.printStackTrace(); } //5.关闭线程池 exectorService.shutdown(); } }