概念:
什么是进程/线程?
进程可以理解成一个独立的程序,比如当我们打开任务管理器时,在进程栏可以看到各个应用的运行情况,我们可以把正在运行的这些应用程序看作一个个的进程。
而线程是进程在单独的一个任务,一个进程可能包含多个线程。线程所执行的任务是线性的(从前到后),一条线程无法同时多个任务。
什么是并行/并发?
并行指在同一时刻,有多个任务在不同的处理器或核心上同时执行,主要指硬件方面的多任务处理。就像有多个工人同时在不同的工作区域工作,每个工人都在独立地完成自己的任务,彼此之间没有干扰,能真正地同时进行。
而并发指在同一时间段内,有多个任务在交替执行,主要指软件层面的多任务处理。并发在宏观上给人一种多个任务同时进行的感觉,但在微观上,在同一时刻可能只有一个任务在执行,只是任务切换快,让用户感觉是在同时进行。
什么是多线程?
多线程是指从软硬件上实现的多条执行流程的技术
实现:
在Java中,线程的实现有三种方式:
一 直接继承Thread类,必须重写run方法:
先写继承Thread类的实现类
public class MyThread extends Thread{
@Override
public void run(){
//线程任务
}
}
再创建实现类的对象调用start方法开始线程任务
Thread thread = new MyThread();
thread.start();
(注:主线程放在子线程前会导致主线程先执行完再执行子线程)
二 实现Runnable接口
先写Runnable接口的实现类,重写run方法
public class MyRunnable implements Runnable{
@Overrite
public void run(){
//线程任务
}
}
新建任务对象交给线程对象(作为参数传给线程构造方法),用线程对象调用start方法启动线程
Runnable run = new MyRunnable();
new Thread(run).start();
简化写法:
Runnable run = new Runnable(){
@Overrite
public void run(){
//线程方法
}
};
new Thread(run).start();
new Thread(new Runnable(){
@Override
public void run(){
//线程方法
}
}).start();
三 实现Callable接口
先写Callable接口的实现类,重写call方法
public class MyCallable implements Callable<返回结果类型>{
@Override
public 返回结果类型 call() throws Exception{
//线程方法
//返回结果(可以用get方法获得返回的结果)
}
}
创建Callable实现对象,并封装为FutureTask对象,再把FutureTask对象传给Thread对象
Callable<返回结果类型> call = new MyCallable();
FutureTask<返回结果类型> fu = new FutureTask<>(call);
new Thread(fu).start();
操作方法:
常用方法:
public void run() //线程任务方法
public void start() //线程启动方法
public String getName() //获取当前线程名称
public void setName(String name) //设置线程名称
public static Thread currentThread() //获取当前线程
public static void sleep(long time) //让当前线程休眠time后执行
public final void join() //调用方法使线程先执行完
构造方法:可以以String Runnable或者两个一起作为构造的参数
线程安全:
多个线程同时操作一个共享资源可能导致线程安全问题
解决方法:(线程同步)
方法一 同步代码块
synchronized(共享资源){
//访问共享资源的代码
}
调用静态方法test时用类名.class作为锁
方法二 同步方法
修饰符 synchronnized 返回值类型 方法名称(形参列表){
//线程方法
}
调用该方法时可以保证线程安全
方法三 Lock锁
创建锁对象(实现类为ReentrantLock),然后在需要的地方加锁和解锁
Lock lock = new ReentrantLock();
lock.lock(); //加锁
//线程方法(try catch final形式)
lock.unlock(); //解锁