并行:同一时刻同时执行多个任务
并发:同一时间处理多个任务,但不一定同时执行多个任务
进程:正在运行的程序,独占内存空间(取决于内存)
进程的特点:
-
进程是系统运行程序的基本单位
-
每一个进程都有自己独立的一块内存空间、一组系统资源
-
每一个进程的内部数据和状态都是完全独立的
-
当一个应用程序运行的时候会产生一个进程
线程:线程是进程中执行运算的最小单位,一个进程在其执行过程中可以产生多个线程,而线程必须在某个进程中执行(取决于CPU)
多线程:在一个进程中运行多个线程
线程和进程的区别与联系:
-
一个进程中至少要有一个线程
-
资源分配给进程,同一进程的所有线程共享该进程的所有资源(如内存)
-
处理器分配给线程,即真正在处理器上运行的是线程
Java是抢占式调度(依据优先级)
创建线程的三种方式:
1.继承Thread类,重写run(),开启start()
run()中存放需要执行的代码
start() //开启线程
注:若用Thread类的对象调用run()表示调用方法,而不是开启线程
2.Runnable
接口,重写run(),开启start()
currentThread()
//返回当前进程
使用时需创建Thread对象,在其构造中传入子对象
Thread与Runnable区别:
继承性: Thread是一个类,因此如果继承Thread类,子类就不能再然承其他的类了,而实现Runnable接口可以然承其他类,这样可以免Java中单继承带来的限制。
接口性: Runnable是一个接口,需要实现run()方法,而Thread是一个类,可以直接创建对象,无需实现接口。
代码耦合: 使用Runnable可以将任务的代码和线程的代码解耦,从而可以更加灵活地组织代码。
线程状态: 创建Thread对象后,可以直接调用start()方法启动线程,而使用Runnable需要先创建Thread对象,然后将Runnable对象传递给Thread对象,最后调用start()方法启动线程。
3.实现Callable接口
Callable与Runnable区别:
-
Callable接口的call()方法可以有返回值,而Runnable接口的run()方法没有返回值
-
call()方法可以抛出受检异常,而run()方法不能抛出异常
-
Callable接口的结果可以通过Future对象获取,可以用来判断任务的状态、取消任务或获取任务的状态
FutureTask
类:
实现了Future和Runnable接口的类,可以用来表示一个异步计算的结果,可以用get()获得结果
构造:
public FutureTask(Runnable runnable,V result)
public FutureTask(Runnable runnable)
使用:
实现Callable接口,重写call()方法,返回V
先创建FutureTask对象,传入Callable,创建Thread对象,传入
Thread类
构造:
public Thread()
public Thread(String name)
public Thread(Runnable target)
public Thread(Runnable target,String name)
方法:
currentThread() //获取当前线程对象
statr() //开启线程,同一个对象重复调用出错
static sleep(long millis) //线程不会丢失CPU任何使用权,以指定毫秒暂停
getName() //获取当前线程名字
setName() //设置名字
getPriority() //获取优先级
setPriority() //设置高的会比低的抢占几率大一些,但一些低的仍会强到
isAlive() //线程状态启动并且执行为true
join() //等待线程死亡,等同于join(0),等待该进程死亡才能执行其他的
join(long millis) //等待进程millis号秒后,不等,与其他资源一起抢占
interrupt() //中断这个线程
static yield() //让步状态,让其他优先级相等或高的先执行,接下来这些会被调度,此时还会与其他抢夺资源,不是睡眠
sleep()方法与yield()方法的区别:
sleep()与yield()
1.使当前线程进入被阻塞的状态;将当前线程转入暂停执行的状态
2.即使没有其他等待运行的线程,当前线程也会等待指定的时间;如果没有其他等待执行的线程,当前线程会马上回复执行
3.其他等待线程的机会是均等的;会运行优先级相同或更高的线程