进程、线程、多线程
- 线程就是独立的执行路径
- 在程序执行时,即使没有自己创建线程,后台也会有多个线程,如主线程,gc线程
- main()称之为主线程,为系统的入口,用于执行整个系统
- 在一个进程中,如果开辟了多个线程,线程的运行由调度器安排调度,调度器与操作系统紧密相关的,先后顺序是不能人为干预的
- 对同一份资源操作时,会存在资源抢夺的问题,需要加入并发控制
- 线程会带来额外的开销,如cup调度时间,并发控制开销
- 每个线程在自己的工作内存交互,内存控制不当,会造成数据不一致
线程创建
方式一:继承Thread类
不建议使用:避免oop单继承局限性
- 继承Thread类
- 重写run()方法,编写线程执行体
- 创建该测试类对象,直接调用start()开启线程
public class TestThread01 extends Thread {
//线程入口
@Override
public void run() {
//线程体
for (int i = 0; i < 20; i++) {
System.out.println("吃饭======"+i);
}
}
//主线程
public static void main(String[] args) {
//创建该测试类对象
TestThread01 testThread01 = new TestThread01();
//启动该线程
testThread01.start();
for (int i = 0; i < 200; i++) {
System.out.println("睡觉-------"+i);
}
}
}
证明线程是交替执行的,由cup调度
方式二:实现Runnable
推荐使用:避免单继承局限性,灵活方便,方便同一个对象被多个线程使用
- 实现Runnable接口
- 实现run()方法,编写线程执行体
- 创建该测试类对象
- 创建Thread对象,将该测试类对象丢入Thread对象
- Thread对象调用start()开启线程
public class TestThread02 implements Runnable{
@Override
public void run() {
for (int i = 0; i < 20; i++) {
System.out.println("吃饭======"+i);
}
}
public static void main(String[] args) {
//创建该测试类对象
TestThread02 testThread02 = new TestThread02();
//创建Thread对象,通过Thread对象来开启线程(代理)
//将该测试类对象丢入Thread对象
Thread thread = new Thread(testThread02);
//启动该线程
thread.start();
for (int i = 0; i < 200; i++) {
System.out.println("睡觉-------"+i);
}
}
}
方式三:实现callable接口
- 实现callable接口,需要返回值类型
- 重写call方法,需要抛出异常
- 创建目标对象
- 创建执行服务
- 提交执行
- 获取结果
- 关闭服务
public class TestThread03 implements Callable<String> {
public String name;
public TestThread03(String name){
this.name=name;
}
@Override
public String call() throws Exception {
for (int i = 0; i < 20; i++) {
System.out.println(name+"吃饭======"+i);
}
return "完成";
}
public static void main(String[] args) throws ExecutionException, InterruptedException {
TestThread03 t1 = new TestThread03("zs");
TestThread03 t2 = new TestThread03("ls");
//创建执行服务,线程池设置为2
ExecutorService service = Executors.newFixedThreadPool(2);
//提交执行
Future<String> f1 = service.submit(t1);
Future<String> f2 = service.submit(t2);
//获取结果
String result1 = f1.get();
System.out.println(result1);//完成
String result2 = f1.get();
System.out.println(result2);//完成
//关闭服务
service.shutdownNow();
}
}