文章目录
继承和线程以及线程的创建
JVM内存结构
虚拟机栈:用于存放方法的基本信息, 局部变量,操作数,
Java的内存模型:站在内存模型上理解堆和方法去时是线程共享区域,虚拟机栈,本地方法栈,程序计数器是线程私有的,
当线程处于New状态时仅仅在堆空间分配了内存,运行中的线程会有虚拟机栈存在。
进程和线程
-
进程:一段正在进行的程序 一个程序可以同时执行多个任务。进程是并发程序在执行过程中资源分配和管理的基本单位
-
线程:进程中的每一个任务。线程被称为轻量级进程。线程执行程序的最小单位,一个进程拥有多个线程 ,各个线程共享进程的地址空间以及一些进程级别的其他资源。
3.区别:
- 内存空间的区别
进程是有独立的内存空间,每个进程之间是相互独立的,互不干扰。
线程是有共享的内存空间
- 安全性
进程间是相互独立的,一个线程的崩溃不会影响其他的进程,进程是安全的。
线程反之
线程创建
实现Runable接口
- 自定义实现一个Runable接口的实现类,并实现run方法
public class ImplRunable implements Runnable{
@Override
public void run() {
//
System.out.println(Thread.currentThread().getName()+"--实现runable接口");
}
- 实例化自定义Runable实现类
// 创建自定义的实例 -》 任务体
ImplRunable runable = new ImplRunable();
3. 创建Theread类实例,将实例化的runable实例作为参数传递
Thread thread = new Thread(runable);
4. 启动子线程,调用Thread实例的start方法
thread.start();
System.out.println(thread.currentThread().getName()+"--主线程main");
5. 调用方法
public static void main(String[] args) {
textCreateThread();
}
Runable是任务体,thread类是线程对象,线程是用来执行任务的
直接继承Thread类
- 自定义类继承Thread,重写run方法。
- 创建自定义类的实例
- 启动start类
实现Callable接口
- 自定义类实现callable接口 ,重写call方法 具有返回值
public class implCallable implements Callable<String> { // 实现callable接口创建线程
@Override
public String call() throws Exception {
System.out.println(Thread.currentThread().getName()+": 实现callable接口创建线程");
return " ";
}
- callable接口中没有继承thread类,所以需要中间值 FutureTexk,此类实现runableFuture接口,而此接口继承Runable接口
implCallable callable = new implCallable();
FutureTask<String> futureTask = new FutureTask<>(callable);
Thread thread = new Thread(futureTask);
- 启动线程
内部匿名类创建
Thread t1 =new Thread(){
@override
public void run(){
sout("子线程");
}
};
t1.start;
Callable Runable 的区别
-
callable 必须借助Future 才能转成runable 类型,然后才能thread启动线程。
-
Callable类型的任务有返回值,Runable任务不能有返回值
-
Callable规定的方法是call() 方法,而Runable规定的方法是run()方法。
-
Callable中的call方法可以抛出异常,run方法是不能排除异常
-
Callable任务可以拿到Future对象,Future表示异步计算的结果,提供可以检查子线程是否执行完成的方法,可以获得子线程执行的结果 ,通过Future队形可以控制和了解子线程的执行。
异步:操作系统控制,子线程一定是在主线程之前完成。
//Callable实现类是可以在主线程中获取到子线程的执行结果的 因为有 返回值 try { //get方法获取的子线程返回的结果 子线程比主线程先结束 String s = futureTask.get(); System.out.println(Thread.currentThread().getName()+":c:" + s); } catch (InterruptedException e) { e.printStackTrace(); } catch (ExecutionException e) { e.printStackTrace(); }
实现Runable 和继承thread类的区别
- 继承Thread类 就是多个线程各自完成自己的任务,实现Runable接口,就是多个线程完成一个任务,可以避免会java单继承性带来的局限
- 使用继承Thread类是不能继承其他类,而Runable方式可以
- 继承Thread是无法实现资源共享,而Runable接口可以实现资源共享
- 实现Runable接口代码更健壮,任务和线程是解耦合的,代码更清晰,代码和数据是相互独立。
耦合:软件体系内不同模块之间(class,方法)的连接程度的度量