进程是由至少一个或者多个线程组成的;线程是进程的最小的基本单位
特性:
1.抢占式运行【重要】
给程序分配CPU,按时间片来执行,单位时间片抢占式执行。随机抢占
2.资源共享
同一个进程,有多个线程,这多个线程可以共享同一个数据
实现多线程
1.继承Thread类,重写run方法。
2.实现Runnable接口,重写run方法。
3.实现Callable,重写call方法
//多线程类
public class MyThread implements Callable<Integer> {
@Override
public Integer call() throws Exception {
int sum = 0;
for (int i = 1; i <= 100; i++) {
sum+=i;
}
return sum;
}
}
//多线程启动类
public class Test {
public static void main(String[] args) throws ExecutionException, InterruptedException {
//创建myThread对象(多线程要执行的任务)
MyThread myThread = new MyThread();
//创建FutureTask的对象(作用管理多线程的结果)
FutureTask<Integer> futureTask = new FutureTask<>(myThread);
//创建多线程的对象
Thread thread = new Thread(futureTask);
//启动多线程
thread.start();
//获取多线程的运行结果
Integer integer = futureTask.get();
System.out.println(integer);
}
}
同步代码块
//把共享数据的代码锁起来
//特点1:
锁默认打开,有一个线程进去了,锁自动关闭
//特点2:
里面的代码全部执行完毕,线程出来,锁自动打开
synchronized(锁){
操作共享数据的代码
}
lock锁
虽然我们可以理解同步代码块和同步方法的锁对象问题
但是我们并没有直接看到在哪里加了锁,在哪里释放了锁
为了更清晰的表达如何加锁和释放锁,JDK5以后提供了一个新的锁对象Lock
Lock实现提供比使用synchronized方法和语句可以获得更广泛的锁定对象
Lock中提供了获得锁和释放锁的方法
void lock; 获得锁
void unlodk;释放锁
Lock接口不能直接实例化,采用它的实现类ReentrantLock来实例化
ReentrantLock的构造方法
ReentrantLock();创建一个ReentrantLock的实例