线程创建方式

一、继承Thread类,重写run方法,实现创建一个线程
package com.wuhao.thread;

import java.util.Date;

/**
 * 自定义线程
 */
public class MyThread extends Thread{
    public void run() {
        for (int i = 0;i<10;i++
        ){
            System.out.println("子线程执行时间:"+new Date().getTime());
        }
    }
}


package com.wuhao.thread;

import java.util.Date;

/**
 * 测试类
 */
public class ThreadTest {

    public static void main(String[] args) {
        //1.创建自定义线程实例
        MyThread myThread = new MyThread();
        //2、启动线程
        myThread.start();
        //3、执行main主线程
        for (int i = 0;i<10;i++){
            System.out.println("主线程执行时间:"+new Date().getTime());
        }
    }
}


"C:\Program Files\Java\jdk1.8.0_131\bin\java.exe" "-javaagent:C:\Program Files\JetBrains\IntelliJ IDEA 2018.2.5\lib\idea_rt.jar=63359:C:\Program Files\JetBrains\IntelliJ IDEA 2018.2.5\bin" -Dfile.encoding=UTF-8 -classpath "C:\Program Files\Java\jdk1.8.0_131\jre\lib\charsets.jar;C:\Program Files\Java\jdk1.8.0_131\jre\lib\deploy.jar;C:\Program Files\Java\jdk1.8.0_131\jre\lib\ext\access-bridge-64.jar;C:\Program Files\Java\jdk1.8.0_131\jre\lib\ext\cldrdata.jar;C:\Program Files\Java\jdk1.8.0_131\jre\lib\ext\dnsns.jar;C:\Program Files\Java\jdk1.8.0_131\jre\lib\ext\jaccess.jar;C:\Program Files\Java\jdk1.8.0_131\jre\lib\ext\jfxrt.jar;C:\Program Files\Java\jdk1.8.0_131\jre\lib\ext\localedata.jar;C:\Program Files\Java\jdk1.8.0_131\jre\lib\ext\nashorn.jar;C:\Program Files\Java\jdk1.8.0_131\jre\lib\ext\sunec.jar;C:\Program Files\Java\jdk1.8.0_131\jre\lib\ext\sunjce_provider.jar;C:\Program Files\Java\jdk1.8.0_131\jre\lib\ext\sunmscapi.jar;C:\Program Files\Java\jdk1.8.0_131\jre\lib\ext\sunpkcs11.jar;C:\Program Files\Java\jdk1.8.0_131\jre\lib\ext\zipfs.jar;C:\Program Files\Java\jdk1.8.0_131\jre\lib\javaws.jar;C:\Program Files\Java\jdk1.8.0_131\jre\lib\jce.jar;C:\Program Files\Java\jdk1.8.0_131\jre\lib\jfr.jar;C:\Program Files\Java\jdk1.8.0_131\jre\lib\jfxswt.jar;C:\Program Files\Java\jdk1.8.0_131\jre\lib\jsse.jar;C:\Program Files\Java\jdk1.8.0_131\jre\lib\management-agent.jar;C:\Program Files\Java\jdk1.8.0_131\jre\lib\plugin.jar;C:\Program Files\Java\jdk1.8.0_131\jre\lib\resources.jar;C:\Program Files\Java\jdk1.8.0_131\jre\lib\rt.jar;C:\Users\Administrator\IdeaProjects\multiThread\thread_create_demo\target\classes" com.wuhao.thread.ThreadTest
主线程执行时间:1589007456050
子线程执行时间:1589007456050
主线程执行时间:1589007456050
子线程执行时间:1589007456051
主线程执行时间:1589007456051
子线程执行时间:1589007456051
子线程执行时间:1589007456051
子线程执行时间:1589007456051
子线程执行时间:1589007456051
子线程执行时间:1589007456051
子线程执行时间:1589007456051
子线程执行时间:1589007456051
主线程执行时间:1589007456051
主线程执行时间:1589007456051
主线程执行时间:1589007456051
子线程执行时间:1589007456051
主线程执行时间:1589007456051
主线程执行时间:1589007456051
主线程执行时间:1589007456051
主线程执行时间:1589007456051

Process finished with exit code 0


总结:
从上述执行时间来看,主子线程执行时间上具有重叠部分,说明主子线程可以并发执行。
二、实现Runnable接口重写run方法实现线程的创建
package com.wuhao.thread;

import java.util.Date;

/**
 * 自定义实现Runnable接口实现创建线程
 */
public class MyRunnable implements Runnable{
    @Override
    public void run() {
        for (int i = 0;i<10;i++){
            System.out.println(Thread.currentThread().getName()+""+i+"执行时间:"+new Date().getTime());
        }
    }
}


package com.wuhao.thread;

import java.util.Date;

/**
 * 测试类
 */
public class ThreadTest {

    public static void main(String[] args) {
        //1、main主线程打印信息
        for (int i = 0;i<10;i++){
            System.out.println("主线程执行时间:"+new Date().getTime());
        }
        //2、通过thread类执行MyRunnable类
        Thread thread = new Thread(new MyRunnable());
        thread.start();
    }
    }



"C:\Program Files\Java\jdk1.8.0_131\bin\java.exe" "-javaagent:C:\Program Files\JetBrains\IntelliJ IDEA 2018.2.5\lib\idea_rt.jar=63249:C:\Program Files\JetBrains\IntelliJ IDEA 2018.2.5\bin" -Dfile.encoding=UTF-8 -classpath "C:\Program Files\Java\jdk1.8.0_131\jre\lib\charsets.jar;C:\Program Files\Java\jdk1.8.0_131\jre\lib\deploy.jar;C:\Program Files\Java\jdk1.8.0_131\jre\lib\ext\access-bridge-64.jar;C:\Program Files\Java\jdk1.8.0_131\jre\lib\ext\cldrdata.jar;C:\Program Files\Java\jdk1.8.0_131\jre\lib\ext\dnsns.jar;C:\Program Files\Java\jdk1.8.0_131\jre\lib\ext\jaccess.jar;C:\Program Files\Java\jdk1.8.0_131\jre\lib\ext\jfxrt.jar;C:\Program Files\Java\jdk1.8.0_131\jre\lib\ext\localedata.jar;C:\Program Files\Java\jdk1.8.0_131\jre\lib\ext\nashorn.jar;C:\Program Files\Java\jdk1.8.0_131\jre\lib\ext\sunec.jar;C:\Program Files\Java\jdk1.8.0_131\jre\lib\ext\sunjce_provider.jar;C:\Program Files\Java\jdk1.8.0_131\jre\lib\ext\sunmscapi.jar;C:\Program Files\Java\jdk1.8.0_131\jre\lib\ext\sunpkcs11.jar;C:\Program Files\Java\jdk1.8.0_131\jre\lib\ext\zipfs.jar;C:\Program Files\Java\jdk1.8.0_131\jre\lib\javaws.jar;C:\Program Files\Java\jdk1.8.0_131\jre\lib\jce.jar;C:\Program Files\Java\jdk1.8.0_131\jre\lib\jfr.jar;C:\Program Files\Java\jdk1.8.0_131\jre\lib\jfxswt.jar;C:\Program Files\Java\jdk1.8.0_131\jre\lib\jsse.jar;C:\Program Files\Java\jdk1.8.0_131\jre\lib\management-agent.jar;C:\Program Files\Java\jdk1.8.0_131\jre\lib\plugin.jar;C:\Program Files\Java\jdk1.8.0_131\jre\lib\resources.jar;C:\Program Files\Java\jdk1.8.0_131\jre\lib\rt.jar;C:\Users\Administrator\IdeaProjects\multiThread\thread_create_demo\target\classes" com.wuhao.thread.ThreadTest
主线程执行时间:1589008598569
主线程执行时间:1589008598569
主线程执行时间:1589008598569
主线程执行时间:1589008598569
主线程执行时间:1589008598569
主线程执行时间:1589008598569
主线程执行时间:1589008598569
主线程执行时间:1589008598569
主线程执行时间:1589008598569
主线程执行时间:1589008598569
Thread-0第0执行时间:1589008598582
Thread-0第1执行时间:1589008598582
Thread-0第2执行时间:1589008598582
Thread-0第3执行时间:1589008598582
Thread-0第4执行时间:1589008598582
Thread-0第5执行时间:1589008598582
Thread-0第6执行时间:1589008598582
Thread-0第7执行时间:1589008598582
Thread-0第8执行时间:1589008598582
Thread-0第9执行时间:1589008598582

Process finished with exit code 0


总结:
由线程执行时间可以看出,实现了主子线程的创建
三、实现callable接口实现
FutrueTask 实现RunnableFutrue接口,制定返回值泛型类型,RunnableFutrue继承Runnable接口和Futrue,
重新call方法,具有返回值
package com.wuhao.thread;

import java.util.Date;
import java.util.concurrent.Callable;

/**
 * 自定义实现Callable接口创建线程
 */
public class MyCallable implements Callable<String> {
    @Override
    public String call() throws Exception {
        for (int i = 0;i<10;i++){
            System.out.println(Thread.currentThread().getName()+""+i+"次执行时间:"+new Date().getTime());
        }
        return "子线程执行完毕";
    }
}


package com.wuhao.thread;

import java.util.Date;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.FutureTask;

/**
 * 测试类
 */
public class ThreadTest {

    public static void main(String[] args) {
        //1、main主线程打印信息
        for (int i = 0; i < 10; i++) {
            System.out.println("主线程执行时间:" + new Date().getTime());
        }
        //2、创建FutrueTask实例,创建Callable接口
        //3、创建Thread实例,执行FutrueTask
        //4、获取打印子线程执行结果
        FutureTask<String> task = new FutureTask<>( new MyCallable());
        Thread thread = new Thread(task,"myCallable");
        thread.start();
        try {
            String result = task.get();
            System.out.println("子线程执行结果:"+result);
        } catch (InterruptedException e) {
            e.printStackTrace();
        } catch (ExecutionException e) {
            e.printStackTrace();
        }
    }
}


"C:\Program Files\Java\jdk1.8.0_131\bin\java.exe" "-javaagent:C:\Program Files\JetBrains\IntelliJ IDEA 2018.2.5\lib\idea_rt.jar=63390:C:\Program Files\JetBrains\IntelliJ IDEA 2018.2.5\bin" -Dfile.encoding=UTF-8 -classpath "C:\Program Files\Java\jdk1.8.0_131\jre\lib\charsets.jar;C:\Program Files\Java\jdk1.8.0_131\jre\lib\deploy.jar;C:\Program Files\Java\jdk1.8.0_131\jre\lib\ext\access-bridge-64.jar;C:\Program Files\Java\jdk1.8.0_131\jre\lib\ext\cldrdata.jar;C:\Program Files\Java\jdk1.8.0_131\jre\lib\ext\dnsns.jar;C:\Program Files\Java\jdk1.8.0_131\jre\lib\ext\jaccess.jar;C:\Program Files\Java\jdk1.8.0_131\jre\lib\ext\jfxrt.jar;C:\Program Files\Java\jdk1.8.0_131\jre\lib\ext\localedata.jar;C:\Program Files\Java\jdk1.8.0_131\jre\lib\ext\nashorn.jar;C:\Program Files\Java\jdk1.8.0_131\jre\lib\ext\sunec.jar;C:\Program Files\Java\jdk1.8.0_131\jre\lib\ext\sunjce_provider.jar;C:\Program Files\Java\jdk1.8.0_131\jre\lib\ext\sunmscapi.jar;C:\Program Files\Java\jdk1.8.0_131\jre\lib\ext\sunpkcs11.jar;C:\Program Files\Java\jdk1.8.0_131\jre\lib\ext\zipfs.jar;C:\Program Files\Java\jdk1.8.0_131\jre\lib\javaws.jar;C:\Program Files\Java\jdk1.8.0_131\jre\lib\jce.jar;C:\Program Files\Java\jdk1.8.0_131\jre\lib\jfr.jar;C:\Program Files\Java\jdk1.8.0_131\jre\lib\jfxswt.jar;C:\Program Files\Java\jdk1.8.0_131\jre\lib\jsse.jar;C:\Program Files\Java\jdk1.8.0_131\jre\lib\management-agent.jar;C:\Program Files\Java\jdk1.8.0_131\jre\lib\plugin.jar;C:\Program Files\Java\jdk1.8.0_131\jre\lib\resources.jar;C:\Program Files\Java\jdk1.8.0_131\jre\lib\rt.jar;C:\Users\Administrator\IdeaProjects\multiThread\thread_create_demo\target\classes" com.wuhao.thread.ThreadTest
主线程执行时间:1589009519143
主线程执行时间:1589009519144
主线程执行时间:1589009519144
主线程执行时间:1589009519144
主线程执行时间:1589009519144
主线程执行时间:1589009519144
主线程执行时间:1589009519144
主线程执行时间:1589009519144
主线程执行时间:1589009519144
主线程执行时间:1589009519144
myCallable第0次执行时间:1589009519147
myCallable第1次执行时间:1589009519147
myCallable第2次执行时间:1589009519147
myCallable第3次执行时间:1589009519147
myCallable第4次执行时间:1589009519147
myCallable第5次执行时间:1589009519147
myCallable第6次执行时间:1589009519147
myCallable第7次执行时间:1589009519147
myCallable第8次执行时间:1589009519147
myCallable第9次执行时间:1589009519147
子线程执行结果:子线程执行完毕

Process finished with exit code 0


四、通过线程池创建线程
线程池本质上是一个线程的容器,在开发中,需要创建线程的时候则直接去线程池中去拿线程,执行完毕后再释放资源,这种方式效率较高。
package com.wuhao.thread;

        import java.util.Date;

/**
 * 自定义实现Runnable接口实现创建线程
 */
public class MyRunnable implements Runnable{
    @Override
    public void run() {
        for (int i = 0;i<10;i++){
            System.out.println(Thread.currentThread().getName()+""+i+"执行时间:"+new Date().getTime());
        }
    }
}


package com.wuhao.thread;

import java.util.Date;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

/**
 * 线程池测试类
 */
public class ThreadPoolTest {
    public static void main(String[] args) {
        //1、使用线程池创建线程,Executors获取线程对象
        ExecutorService executorService = Executors.newFixedThreadPool(10);
        //2、通过线程池对象获取线程并执行MyRunnable实例
        executorService.execute(new MyRunnable());
        //3、主线程打印信息
        for (int i = 0; i < 10; i++) {
            System.out.println("主线程执行时间:" + new Date().getTime());
        }
    }
}


"C:\Program Files\Java\jdk1.8.0_131\bin\java.exe" "-javaagent:C:\Program Files\JetBrains\IntelliJ IDEA 2018.2.5\lib\idea_rt.jar=63507:C:\Program Files\JetBrains\IntelliJ IDEA 2018.2.5\bin" -Dfile.encoding=UTF-8 -classpath "C:\Program Files\Java\jdk1.8.0_131\jre\lib\charsets.jar;C:\Program Files\Java\jdk1.8.0_131\jre\lib\deploy.jar;C:\Program Files\Java\jdk1.8.0_131\jre\lib\ext\access-bridge-64.jar;C:\Program Files\Java\jdk1.8.0_131\jre\lib\ext\cldrdata.jar;C:\Program Files\Java\jdk1.8.0_131\jre\lib\ext\dnsns.jar;C:\Program Files\Java\jdk1.8.0_131\jre\lib\ext\jaccess.jar;C:\Program Files\Java\jdk1.8.0_131\jre\lib\ext\jfxrt.jar;C:\Program Files\Java\jdk1.8.0_131\jre\lib\ext\localedata.jar;C:\Program Files\Java\jdk1.8.0_131\jre\lib\ext\nashorn.jar;C:\Program Files\Java\jdk1.8.0_131\jre\lib\ext\sunec.jar;C:\Program Files\Java\jdk1.8.0_131\jre\lib\ext\sunjce_provider.jar;C:\Program Files\Java\jdk1.8.0_131\jre\lib\ext\sunmscapi.jar;C:\Program Files\Java\jdk1.8.0_131\jre\lib\ext\sunpkcs11.jar;C:\Program Files\Java\jdk1.8.0_131\jre\lib\ext\zipfs.jar;C:\Program Files\Java\jdk1.8.0_131\jre\lib\javaws.jar;C:\Program Files\Java\jdk1.8.0_131\jre\lib\jce.jar;C:\Program Files\Java\jdk1.8.0_131\jre\lib\jfr.jar;C:\Program Files\Java\jdk1.8.0_131\jre\lib\jfxswt.jar;C:\Program Files\Java\jdk1.8.0_131\jre\lib\jsse.jar;C:\Program Files\Java\jdk1.8.0_131\jre\lib\management-agent.jar;C:\Program Files\Java\jdk1.8.0_131\jre\lib\plugin.jar;C:\Program Files\Java\jdk1.8.0_131\jre\lib\resources.jar;C:\Program Files\Java\jdk1.8.0_131\jre\lib\rt.jar;C:\Users\Administrator\IdeaProjects\multiThread\thread_create_demo\target\classes" com.wuhao.thread.ThreadPoolTest
主线程执行时间:1589010338954
pool-1-thread-1第0执行时间:1589010338954
主线程执行时间:1589010338954
pool-1-thread-1第1执行时间:1589010338954
主线程执行时间:1589010338954
pool-1-thread-1第2执行时间:1589010338954
主线程执行时间:1589010338954
pool-1-thread-1第3执行时间:1589010338954
主线程执行时间:1589010338954
pool-1-thread-1第4执行时间:1589010338954
主线程执行时间:1589010338954
pool-1-thread-1第5执行时间:1589010338954
主线程执行时间:1589010338954
pool-1-thread-1第6执行时间:1589010338954
主线程执行时间:1589010338954
pool-1-thread-1第7执行时间:1589010338954
主线程执行时间:1589010338954
pool-1-thread-1第8执行时间:1589010338954
主线程执行时间:1589010338954
pool-1-thread-1第9执行时间:1589010338954


实现线程创建方式总结:
1、实现接口和Thread类比较
接口适合多个相同程序代码的线程去共享同一资源
接口避免了java中单继承的局限性
接口代码可以多个线程共享,代码和线程独立
线程池只能放入实现Runnable或者Callable接口的线程,不能直接放入Thread的类
java中,每次至少运行两个线程,一个是main主线程,另一个是垃圾收集线程
2、Runnable和Callable接口比较
相同点:
两者都是接口
两者都可以编写多线程接口
两者都需要调用Thread.start()方法启动线程
不同点:
Callable可以返回执行结果,Runnable不需要返回执行结果
Callable接口的call()方法允许抛出异常,Runable接口的run()不允许抛出异常
实现Callable接口可以调用Future.cancle()取消线程的执行,而Runnable接口执行则不能取消
Callable接口中执行返回结果时,需要调用FutrueTask.get()方法实现,此方法会阻塞主线程直接去获取子线程执行结果,当不调用此方法,主线程则不阻塞。

 

posted @ 2020-05-10 09:35  久别重逢  阅读(149)  评论(0编辑  收藏  举报