进程:操作系统(os)中正在执行的应用程序。
线程
1.概念:在进程中,可以同时执行多个任务,每一个人任务可以说是一个线程,线程是进程的工作单位,所以也成为了轻量级的进程。
2.线程的组成部分:
(1)cup:获取时间片
(2)数据:栈空间独立,堆空间共享,每一个线程都有自己独立的栈空间,所有线程共享一个堆空间。
(3)程序代码:利用Java代码实现多线程。
3.代码实现多线程的方式:
(1)第一种方式:
继承java.lang.Thread类,同时覆盖run()方法,线程任务定义在run()方法中。
public class TestThread {
public static void main(String[] args) {
//创建线程对象
MyThread m = new MyThread();
//开启线程
m.start();
}
}
//继承Thread类
class MyThread extends Thread{
//线程任务定义在run()方法中
@Override
public void run() {
for(int i = 0;i<=10;i++) {
System.out.println("----------");
}
}
}
(2)第二种方式:
定义实现Runnable接口,实现接口中run()方法。
public class TestRunnable {
public static void main(String[] args) {
//以多态方式创建目标对象
Runnable r = new RunnableImpl();
//创建线程对象
Thread t = new Thread(r);
//开启线程
t.start();
}
}
//实现接口
class RunnableImpl implements Runnable{
//在run()方法中定义线程任务
@Override
public void run() {
for(int i = 0;i<=10;i++) {
System.out.println("*********");
}
}
}
(3)第三种方式:
①线程池:线程容器,将预先创建好的线程对象存入到线程池中,只要将任务提交给线程池,线程池会分配对象给线程对象完成提交任务,线程池中的对象可以被重复使用。
②好处:避免重复创建线程和销毁,从而提高空间利用和执行效率。
③线程池常用的接口和类:(位于 java.util.concurrent包中)。
a.Executor:线程池的顶级接口。
b.ExecutorService:是Executor的子接口,线程池的核心接口。
I.submit(Runnable task):将线程任务提交给线程池。
submit(Callable task):将线程任务提交给线程池。
II.shutdown():关闭线程池,将线程池对象全部销毁。
c.Executors:获取线程池对象的工具类,其中方法基本都为静态方法。
I. static ExecutorService newFixedThreadPool(int n):获取一个固定数量线程的线程池,参数指定线程池中线程对象的数量
II.static ExecutorService newCachedThreadPool():获取动态数量线程对象的线程池,根据提交的任务需求,不够用时,则自动完成线程创建。
public class TestThreadPool {
public static void main(String[] args) {
//获取线程池对象
ExecutorService pool = Executors.newFixedThreadPool(2);
//将线程任务提交给线程池
Runnable r1 = new Runnable() {
@Override
public void run() {
for(int i =0;i<=10;i++) {
System.out.println("%%%%%%%%%");
}
}
};
//提交任务
pool.submit(r1);
pool.shutdown();
}
}
(4)第四种方式:Callable
①Callable接口:位于java.util.concurrent包中,类似于Runnable接口的应用,对应的对象代表线程任务。Callable是泛型接口。
②接口中的方法: V call():带有返回值的方法,同时可以抛出异常
③ Future是存储submit提交任务执行之后的结果利用 Future中的 get方法获取执行的结果。
Future< T> f= pool.submit(c1);
public class TestCallable {
public static void main(String[] args) throws Exception {
ExecutorService pool = Executors.newFixedThreadPool(2);
Callable<Integer> c1= new Callable<Integer>() {
@Override
public Integer call() throws Exception {
int count = 0;
for(int i = 1;i<=10;i++) {
count+=i;
}
System.out.println("线程一"+count);
return count;
}
};
Callable<Integer> c2= new Callable<Integer>() {
@Override
public Integer call() throws Exception {
int count = 0;
for(int i = 11;i<=20;i++) {
count+=i;
}
System.out.println("线程二:"+count);
return count;
}
};
//分别从线程1和2中获取结果
Future<Integer> f1 = pool.submit(c1);
Future<Integer> f2 = pool.submit(c2);
Integer r1 = f1.get();
Integer r2 = f2.get();
System.out.println("线程总和:"+(r1+r2));
pool.shutdown();
}
}