多线程
一、进程和线程
1.1进程
进程:程序是静止的,只有真正运行时的程序,才被称为进程。
特点:
- 单核CPU在任何时间点上。
- 只能运行一个进程。
- 宏观并行、微观串行。
1.2线程
线程:又称轻量级进程(Light Weight Process)。
- 程序中的一个顺序控制流程,同时也是CPU的基本调度单位。
- 进程由多个线程组成,彼此间完成不同的工作,交替执行,称为多线程。
比如:
- 迅雷是一个进程,当中的多个下载任务即是多个线程。
- Java虚拟机是一个进程,默认包含主线程(main),通过代码创建多个独立线程,与main并发执行。
任何一个线程都具有基本的组成部分:
- CPU时间片:操作系统(OS)会为每个线程分配执行时间。
- 运行数据:
堆空间:存储线程需使用的对象,多个线程可以共享堆中的对象。
栈空间:存储线程需使用的局部变量,每个线程都拥有独立的栈。
1.3创建线程
线程是对象–线程类–创建线程
创建有4种方式:
本质上是一种–就implements Runtable
1.3.1extends Thread
创建:
public class TestThread extends Thread{
// 必须重写run方法
@Override
public void run() {
for (int i = 1; i <+ 100; i++) {
System.out.println(Thread.currentThread().getName() +"--"+ i);
}
}
}
使用:
public static void main(String[] args) {
TestThread t1 = new TestThread();
TestThread t2 = new TestThread();
t1.start();
t2.start();
}
1.3.2implements Runnable
最常用的 – 适合共享数据
public class MyThread implements Runnable{
@Override
public void run() {
for (int i = 1; i <= 10; i++) {
System.out.println(Thread.currentThread().getName() +"--"+ i);
}
}
}
public class TestRun {
public static void main(String[] args) {
MyThread tr = new MyThread();
Thread t1 = new Thread(tr);
Thread t2 = new Thread(tr);
t1.start();
t2.start();
}
}
案例:
定义一个集合,里面存的是1-100,用两个线程随机输出集合中的十个元素,输出完就删除这个元素,不考虑线程安全的问题,用实现接口和继承两种方式 实现,最后的要求是输出剩余元素
1.extends Thread:
public class ExT extends Thread{
ArrayList<Integer> list = new ArrayList<>();
public ExT(ArrayList<Integer> list) {
this.list = list;
}
@Override
public void run() {
for (int i = 0; i < 10; i++) {
int index = (int)(Math.random()*list.size()); // 随机生成集合范围里的下标
// 打印信息
System.out.println(Thread.currentThread().getName() +"-删除的元素为:-"+ list.get(index));
// 删除对用元素
list.remove(index);
}
}
}
public static void main(String[] args) throws InterruptedException {
ArrayList<Integer> list = new ArrayList<>();
for (int i = 1; i <= 100; i++) {
list.add(i);
}
System.out.println(list);
ExT e1 = new ExT(list);
ExT e2 = new ExT(list);
e1.start();
e2.start();
Thread.sleep(500);
System.out.println(list);
}
2.Implements Runtable:
public class ImRun implements Runnable{
ArrayList<Integer> list = new ArrayList<>();
{
for (int i = 1; i <= 100; i++) {
list.add(i);
}
}
@Override
public void run() {
for (int i = 0; i < 10; i++) {
int index = (int)(Math.random()*list.size()); // 随机生成集合范围里的下标
// 打印信息
System.out.println(Thread.currentThread().getName() +"-删除的元素为:-"+ list.get(index));
// 删除对用元素
list.remove(index);
}
}
}
public static void main(String[] args) throws InterruptedException {
ImRun i = new ImRun();
Thread t1 = new Thread(i);
Thread t2 = new Thread(i);
t1.start();
t2.start();
Thread.sleep(500);
System.out.println(i.list);
}
这种是会存在异常(当):
1.3.3Callable接口
1.3.3.1Callable
public interface Callable< V >{
public V call() throws Exception;
}
案例:
计算任务,一个包含了2万个整数的数组,
分拆了多个线程来进行并行计算,最后汇总出计算的结果。
public class CalcCall implements Callable<Integer>{
int[] nums;
public CalcCall() {
}
public CalcCall(int[] nums) {
super();
this.nums = nums;
}
public Integer call(){
int sum = 0;
for (int i = 0; i < nums.length; i++) {
sum += nums[i];
}
return sum;
}
}
public class TestCall {
public static void main(String[] args) throws Exception{
int[] num = new int[20000];
for (int i = 0; i < num.length; i++) {
num[i] = i + 1;
}
int count = 4;
int sum = 0;
List<FutureTask<Integer>> fts = new ArrayList<FutureTask<Integer>>();
for (int i = 0; i < count; i++) {
int[] subNums = new int[num.length/count]