进程和线程
进程是计算机正在运行的一个独立的应用程序,进程是一个动态的概念,必须是运行状态,如果一个应用程序没有启动,那就不是一个进程
线程就是组成进程的基本单位,可以完成特定的功能,一个进程是一个或者多个线程组成的
进程和线程的区别
1.内存空间的区别
进程是有独立空间的,在线程创建时就会分配的空间(例如:堆)
线程有共享空间,也有独立空间
2.安全性
进程之间是相互独立的,一个进程的崩溃不会影响到其他的进程,进程和进程之间是安全的
线程之间存在内存共享,一个线程的崩溃可能会影响到其他线程的执行,线程之间的安全性不如进程
线程的创建:
实现Runable接口
继承Thread类
实现Callable接口
实现Runable接口:
1.创建一个实现Runable接口的类;
2.重写run()方法,我们要实现的线程业务在run()实现
3.创建Runable接口实现类的实例;
4.创建一个线程Thread线程实例来执行任务体
5.调用start()启动此线程
举例:
实现Runable接口的类
并重写run();
public class Runable212 implements Runnable {
@Override
public void run() {
System.out.println(Thread.currentThread().getName() + " 子线程正在执行" + i);
}
}
线程调用:
//3.创建Runable接口实现类的实例;;
Runable212 runable212 = new Runable212();
//4.创建一个线程Thread线程实例来执行任务体
Thread thread = new Thread(runable212);
//调用start()启动此线程
thread.start();
匿名类实现方式:
new Thread(new Runnable() {
@Override
public void run() {
System.out.println(Thread.currentThread().getName() + " 子线程正在执行" + i);
}
}).start();
继承Thread类
1、创建类:继承自Thread(extend Thread) ,重写run方法
2、实例化自定义的Thread的子类
3.启动子线程
举例:
创建类:继承自Thread(extend Thread) ,重写run方法
class MyThread extends Thread{
@Override
public void run() {
System.out.println(Thread.currentThread().getName()+"子线程");
}
}
实例化自定义的Thread的子类并启动线程
//实例化自定义的Thread的子类
MyThread myThread = new MyThread();
//启动子线程
myThread.start();
实现Callable方法
Callable接口提供了call方法,方法具有返回值,通过泛型类定义的,且可以抛出异常
通过Callable接口来创建子线程步骤:
1、实现一个Callable接口的实现类,实现call方法
2、实例化一个Callable的实例对象
3、创建一个FutureTask类型的对象实例,并传入Callable的实例对象
4、创建Thread的实例,将FutureTask实例对象传入
5、启动子线程
举例:
1、实现一个Callable接口的实现类,实现call方法
注:call()返回类型为实现接口时的泛型的类型
class Callable212 implements Callable<String>{
@Override
public String call() throws Exception {
System.out.println(Thread.currentThread().getName()+"123");
return "callable212";
}
}
启动线程:
//实例化一个Callable的实例对象
Callable212 callable212 = new Callable212();
//创建一个FutureTask类型的对象实例,并传入Callable的实例对象
FutureTask<String> task = new FutureTask<>(callable212);
//创建Thread的实例,将FutureTask实例对象传入,启动子线程
new Thread(task).start();
匿名类形式:
new Thread( new FutureTask<String>(new Callable<String>() {
@Override
public String call() throws Exception {
System.out.println("懂了");
return "匿名类";
}
})).start();
问题:
一.Runable和Thread形式创建多线程的区别?
1.实例化线程的方式不同分别为进程Thread和实现Runnable接口
因为接口可多实现而类只能继承一个所以Runnable实现方式更加灵活。也更加同用
2.Runnable方式实现的线程方便数据共享,多个线程可以操作同一个变量,符合大多数业务逻辑
3、线程池相关:线程池只接受Runnable、Callable类线程,不能直接放入继承Thread的类。
综上:我们平时使用应默认使用Runnable方式的
二.Callable和Runable接口的区别?
Runnable接口中的run()方法的返回值是void,它做的事情只是纯粹地去执行run()方法中的代码而已;Callable接口中的call()方法是有返回值的,是一个泛型,和Future、FutureTask配合可以用来获取异步执行的结果。
Callable接口实现类中run()方法允许将异常向上抛出,也可以直接在内部处理(try...catch); 而Runnable接口实现类中run()方法的异常必须在内部处理掉,不能向上抛出