之前我们的代码中,只存在一个main方法,所有要执行的代码都要在main方法中执行,我们使用的是单核CPU,而并发编程更充分利用多核CPU资源,并且有些任务场景需要“等待IO”,为了让等待IO的时间能够去做一些其他的工作,也需要用到并发线程。所以我们就需要用到多线程编程。
目录
进程与线程
线程
一个线程就是一个“执行流”,每个线程之间都可以按照顺序执行自己的代码,多个线程之间“同时”执行着多份代码,是操作系统调度的最小单位。
进程
进程是计算机中的程序关于某数据集合上的一次运行活动,是操作系统进行资源分配的最小单位,是操作系统结构的基础。
线程和进程的区别
1.进程包含线程,每个进程至少有一个线程存在,即主线程。
2.进程和进程之间不共享内存空间,同一个进程的线程之间共享同一个内存空间。
3.进程是系统分配资源的最小单位,线程是系统调度的最小单位。
创建线程的方法
使用Thread类和Runnable接口创建线程都需要重写run()方法,线程需要用对象start()方法启动。
方法 1 继承Thread类
创建一个类继承Thread类
class MyThread extends Thread{
@Override
public void run(){
System.out.println("hello 多线程");
}
}
创建一个MyThread类的实例,和创建普通的对象相同,用new
MyThraed t1 = new MyThread();
方法 2 实现 Runnable 接口
创建一个类实现Runnable接口
class MyRunnable implements Runnable{
@Override
public void run(){
System.out.println("hello 多线程");
}
}
创建一个实例:调用Thread的构造方法将Runnable对象输入
Thread t2 = new Thread(new MyRunnable());
其他变形
1.匿名内部类创建Thread子类对象
Thread t3 = new Thread(){
@Override
public void run(){
System.out.println("hello 多线程");
}
};
2.匿名内部类创建Runnable子类对象
Thread t4 = new Thread(new Runnable()){
@Override
public void run(){
System.out.println("hello 多线程");
}
};
3.lambda表达式创建Runnable子类对象
Thread t5 = new Thread(()->System.out.println("hello 多线程"));
// 或者
Thread t5 = new Thread(()->{
System.out,println("hello 多线程");
});
4.创建匿名内部类实现Callable接口
需要重写call()方法,并且有返回值,其余的创建方法都没有返回值。
Callable<Integer> callable = new Callable<>(){
@Override
public Integer call() throws Exception{
int num = 0;
for(int i = 0;i < 10;i++){
num += i;
}
return num;
}
};
FutureTask<Integer> funturetask = new FutureTask<>(callable);
Thread t6 = new Thread(futureTask);
t6.start();
int result = futureTask.get();
System.out.println(result);