创建线程方式的理解

147 阅读3分钟

1、线程与进程的区别?

进程:是程序的某次执行过程,是系统运行的基本单位(例如:LOL,360卫士...);
线程:是执行的最小单位,在某个程序的执行过程中可以产生多条线程,比如360卫士在查杀病毒的时候也可以修复网络;

进程是一个独立事件,而线程是相互干扰的;
在运行时数据区(JVM)中描述了哪些是线程私有或者共有的区域(后文会讲接Jvm);
在内存模型(JMM)中,每条线程都有自己的工作内存,通过内存模型中约定的协议与主内存产生信息交流(后文讲解);

在此也顺便提一嘴成员变量与局部变量的区别:(感受下堆、栈区域)
1、成员变量存在于类中方法外,随着对象的创建而存在,随着对象的消失而消失;
2、局部变量存在于方法中,随着方法执行而产生方法结束而销毁;
3、新建的对象存在堆内存中:成员变量--->堆内存;
4、方法进栈:局部变量存在于栈内存中;
5、成员变量有初始化默认值;
6、局部变量必须赋值才可以使用;
......

2、创建线程的方式

2.1 没有返回值的线程创建

1、继承Thread类:
public class ThreadDemo extends Thread {
	final static int count = 2;
    @Override
    public void run() {
        for (int i = 0; i < count; i++) {
            System.out.println(Thread.currentThread().getName() + "--->" +i);
        }
    }
    public static void main(String[] args) {
        ThreadDemo threadDemo = new ThreadDemo();
        threadDemo.start();
    	}
}
result:
Thread-0---> 0
Thread-0---> 1

注:(线程的各种状态会在并发文中讲解,在此文我们值讨论线程的创建方式)
1.1、继承Thread类,覆盖run()方法 -->(创建线程);
1.2、创建线程对象调用start()方法启动线程    -->(启动线程);

2、实现Runable接口
public class ThreadDemo implements Runnable {
    final static int count = 2;
    @Override
    public void run() {
        for (int i = 0; i < count; i++) {
            System.out.println(Thread.currentThread().getName() + "实现Runnable--->" +i);
        }
    }
    public static void main(String[] args) {
        ThreadDemo threadDemo = new ThreadDemo();
        new Thread(threadDemo).start();
    }
}
result:
Thread-0实现Runnable--->0
Thread-0实现Runnable--->1
注:
2.1、实现Runnable接口;
2.2、重写run方法;
2.3、通过Thread类建立线程对象 ;
2.4、调用.start()启动线程;

关于继承Thread类与实现Runnable接口的区别: 理解继承与实现的区别(单继承、多实现 举例:类是亲爹,只能有一个 接口是干爹,可以有多个)

2.2带有返回值的线程创建方式

1、实现 Callable 接口
public class ThreadDemo implements Callable {
    @Override
    public Object call() throws Exception {
        //线程执行体
        System.out.println("执行了有返回值的线程");
        //返回对象
        return "是我有返回值的";
    }
    public static void main(String[] args) throws ExecutionException, InterruptedException {
        ThreadDemo threadDemo = new ThreadDemo();
        FutureTask<String> futureTask = new FutureTask<>(threadDemo);
        new Thread(futureTask).start();
        String s = futureTask.get();
        System.out.println(s);
    }
}
result:
执行了有返回值的线程
是我有返回值的

注:
1、实现 Callable 接口;
2、重写call()方法;
3、由于Callable不能直接运行,必须要依赖Thread对象     需要转化为Runnable;
4、FutureTask类实现了RunnableFuture接口-->同时继承了Runnable, Future接口;
看源码:  
A:  public class FutureTask<V> implements RunnableFuture<V> 
B:  public interface RunnableFuture<V> extends Runnable, Future<V> {
         void run();
}
5、使用FutureTask提供的get()方法来获取返回值;

鄙人不才,在您面前献丑只愿与您结伴而行,文章若有不当之处,望大佬指点一二;如果我对您有帮助的话,还希望您能点赞分享,成长是一场苦涩的独自修行,我很需要您的陪伴与支持,这也是鄙人不断前行的根本动力,让我们在互相陪伴见证彼此生长的同时能够感染身边最亲近的人一同成长,鄙人在此叩谢!