3种方法
- 继承Thread类
- 实现Runnable接口
- 实现Callable接口
继承Thread类
继承Thread类,覆盖run()方法,在创建Thread类的子类时需要重写 run(),加入线程所要执行的任务代码
自定义类继承Thread类:
package com.ahut.thread;
/**
* @author cheng
* @className: MyThread
* @description:
* @dateTime 2018/6/4 15:43
*/
public class MyThread extends Thread {
private String threadName;
MyThread(String threadName) {
this.threadName = threadName;
}
/**
* @description:
* @author cheng
* @dateTime 2018/6/4 15:43
*/
@Override
public void run() {
for (int i = 0; i < 10; i++) {
System.out.println("当前线程名:" + threadName + ",循环的次数:" + i);
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
测试:
package com.ahut.thread;
import java.util.concurrent.Callable;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.FutureTask;
/**
* @author cheng
* @className: ThreadMain
* @description:
* @dateTime 2018/6/4 15:46
*/
public class ThreadMain {
/**
* @description: 主函数
* @author cheng
* @dateTime 2018/6/4 15:46
*/
public static void main(String[] args){
// 创建线程
MyThread myThread1 = new MyThread("thread-1");
MyThread myThread2 = new MyThread("thread-2");
// 启动线程
myThread1.start();
myThread2.start();
}
}
运行结果:
"C:\Program Files\Java\jdk1.8.0_131\bin\java" "-javaagent:F:\IDEA\IntelliJ IDEA 2017.3.4\lib\idea_rt.jar=57465:F:\IDEA\IntelliJ IDEA 2017.3.4\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;D:\IDEA workspace\ahut-dubbo\ahut-redis\target\test-classes;D:\IDEA workspace\ahut-dubbo\ahut-redis\target\classes;C:\Users\rick\.m2\repository\redis\clients\jedis\2.9.0\jedis-2.9.0.jar;C:\Users\rick\.m2\repository\org\apache\commons\commons-pool2\2.5.0\commons-pool2-2.5.0.jar;C:\Users\rick\.m2\repository\org\springframework\boot\spring-boot-starter-web\2.0.2.RELEASE\spring-boot-starter-web-2.0.2.RELEASE.jar;C:\Users\rick\.m2\repository\org\springframework\boot\spring-boot-starter\2.0.2.RELEASE\spring-boot-starter-2.0.2.RELEASE.jar;C:\Users\rick\.m2\repository\org\springframework\boot\spring-boot\2.0.2.RELEASE\spring-boot-2.0.2.RELEASE.jar;C:\Users\rick\.m2\repository\org\springframework\boot\spring-boot-autoconfigure\2.0.2.RELEASE\spring-boot-autoconfigure-2.0.2.RELEASE.jar;C:\Users\rick\.m2\repository\org\springframework\boot\spring-boot-starter-logging\2.0.2.RELEASE\spring-boot-starter-logging-2.0.2.RELEASE.jar;C:\Users\rick\.m2\repository\ch\qos\logback\logback-classic\1.2.3\logback-classic-1.2.3.jar;C:\Users\rick\.m2\repository\ch\qos\logback\logback-core\1.2.3\logback-core-1.2.3.jar;C:\Users\rick\.m2\repository\org\apache\logging\log4j\log4j-to-slf4j\2.10.0\log4j-to-slf4j-2.10.0.jar;C:\Users\rick\.m2\repository\org\apache\logging\log4j\log4j-api\2.10.0\log4j-api-2.10.0.jar;C:\Users\rick\.m2\repository\org\slf4j\jul-to-slf4j\1.7.25\jul-to-slf4j-1.7.25.jar;C:\Users\rick\.m2\repository\javax\annotation\javax.annotation-api\1.3.2\javax.annotation-api-1.3.2.jar;C:\Users\rick\.m2\repository\org\yaml\snakeyaml\1.19\snakeyaml-1.19.jar;C:\Users\rick\.m2\repository\org\springframework\boot\spring-boot-starter-json\2.0.2.RELEASE\spring-boot-starter-json-2.0.2.RELEASE.jar;C:\Users\rick\.m2\repository\com\fasterxml\jackson\core\jackson-databind\2.9.5\jackson-databind-2.9.5.jar;C:\Users\rick\.m2\repository\com\fasterxml\jackson\core\jackson-annotations\2.9.0\jackson-annotations-2.9.0.jar;C:\Users\rick\.m2\repository\com\fasterxml\jackson\core\jackson-core\2.9.5\jackson-core-2.9.5.jar;C:\Users\rick\.m2\repository\com\fasterxml\jackson\datatype\jackson-datatype-jdk8\2.9.5\jackson-datatype-jdk8-2.9.5.jar;C:\Users\rick\.m2\repository\com\fasterxml\jackson\datatype\jackson-datatype-jsr310\2.9.5\jackson-datatype-jsr310-2.9.5.jar;C:\Users\rick\.m2\repository\com\fasterxml\jackson\module\jackson-module-parameter-names\2.9.5\jackson-module-parameter-names-2.9.5.jar;C:\Users\rick\.m2\repository\org\springframework\boot\spring-boot-starter-tomcat\2.0.2.RELEASE\spring-boot-starter-tomcat-2.0.2.RELEASE.jar;C:\Users\rick\.m2\repository\org\apache\tomcat\embed\tomcat-embed-core\8.5.31\tomcat-embed-core-8.5.31.jar;C:\Users\rick\.m2\repository\org\apache\tomcat\embed\tomcat-embed-el\8.5.31\tomcat-embed-el-8.5.31.jar;C:\Users\rick\.m2\repository\org\apache\tomcat\embed\tomcat-embed-websocket\8.5.31\tomcat-embed-websocket-8.5.31.jar;C:\Users\rick\.m2\repository\org\hibernate\validator\hibernate-validator\6.0.9.Final\hibernate-validator-6.0.9.Final.jar;C:\Users\rick\.m2\repository\javax\validation\validation-api\2.0.1.Final\validation-api-2.0.1.Final.jar;C:\Users\rick\.m2\repository\org\jboss\logging\jboss-logging\3.3.2.Final\jboss-logging-3.3.2.Final.jar;C:\Users\rick\.m2\repository\com\fasterxml\classmate\1.3.4\classmate-1.3.4.jar;C:\Users\rick\.m2\repository\org\springframework\spring-web\5.0.6.RELEASE\spring-web-5.0.6.RELEASE.jar;C:\Users\rick\.m2\repository\org\springframework\spring-beans\5.0.6.RELEASE\spring-beans-5.0.6.RELEASE.jar;C:\Users\rick\.m2\repository\org\springframework\spring-webmvc\5.0.6.RELEASE\spring-webmvc-5.0.6.RELEASE.jar;C:\Users\rick\.m2\repository\org\springframework\spring-aop\5.0.6.RELEASE\spring-aop-5.0.6.RELEASE.jar;C:\Users\rick\.m2\repository\org\springframework\spring-context\5.0.6.RELEASE\spring-context-5.0.6.RELEASE.jar;C:\Users\rick\.m2\repository\org\springframework\spring-expression\5.0.6.RELEASE\spring-expression-5.0.6.RELEASE.jar;C:\Users\rick\.m2\repository\org\springframework\boot\spring-boot-starter-test\2.0.2.RELEASE\spring-boot-starter-test-2.0.2.RELEASE.jar;C:\Users\rick\.m2\repository\org\springframework\boot\spring-boot-test\2.0.2.RELEASE\spring-boot-test-2.0.2.RELEASE.jar;C:\Users\rick\.m2\repository\org\springframework\boot\spring-boot-test-autoconfigure\2.0.2.RELEASE\spring-boot-test-autoconfigure-2.0.2.RELEASE.jar;C:\Users\rick\.m2\repository\com\jayway\jsonpath\json-path\2.4.0\json-path-2.4.0.jar;C:\Users\rick\.m2\repository\net\minidev\json-smart\2.3\json-smart-2.3.jar;C:\Users\rick\.m2\repository\net\minidev\accessors-smart\1.2\accessors-smart-1.2.jar;C:\Users\rick\.m2\repository\org\ow2\asm\asm\5.0.4\asm-5.0.4.jar;C:\Users\rick\.m2\repository\org\slf4j\slf4j-api\1.7.25\slf4j-api-1.7.25.jar;C:\Users\rick\.m2\repository\junit\junit\4.12\junit-4.12.jar;C:\Users\rick\.m2\repository\org\assertj\assertj-core\3.9.1\assertj-core-3.9.1.jar;C:\Users\rick\.m2\repository\org\mockito\mockito-core\2.15.0\mockito-core-2.15.0.jar;C:\Users\rick\.m2\repository\net\bytebuddy\byte-buddy\1.7.11\byte-buddy-1.7.11.jar;C:\Users\rick\.m2\repository\net\bytebuddy\byte-buddy-agent\1.7.11\byte-buddy-agent-1.7.11.jar;C:\Users\rick\.m2\repository\org\objenesis\objenesis\2.6\objenesis-2.6.jar;C:\Users\rick\.m2\repository\org\hamcrest\hamcrest-core\1.3\hamcrest-core-1.3.jar;C:\Users\rick\.m2\repository\org\hamcrest\hamcrest-library\1.3\hamcrest-library-1.3.jar;C:\Users\rick\.m2\repository\org\skyscreamer\jsonassert\1.5.0\jsonassert-1.5.0.jar;C:\Users\rick\.m2\repository\com\vaadin\external\google\android-json\0.0.20131108.vaadin1\android-json-0.0.20131108.vaadin1.jar;C:\Users\rick\.m2\repository\org\springframework\spring-core\5.0.6.RELEASE\spring-core-5.0.6.RELEASE.jar;C:\Users\rick\.m2\repository\org\springframework\spring-jcl\5.0.6.RELEASE\spring-jcl-5.0.6.RELEASE.jar;C:\Users\rick\.m2\repository\org\springframework\spring-test\5.0.6.RELEASE\spring-test-5.0.6.RELEASE.jar;C:\Users\rick\.m2\repository\org\xmlunit\xmlunit-core\2.5.1\xmlunit-core-2.5.1.jar" com.ahut.thread.ThreadMain
当前线程名:thread-1,循环的次数:0
当前线程名:thread-2,循环的次数:0
当前线程名:thread-2,循环的次数:1
当前线程名:thread-1,循环的次数:1
当前线程名:thread-1,循环的次数:2
当前线程名:thread-2,循环的次数:2
当前线程名:thread-1,循环的次数:3
当前线程名:thread-2,循环的次数:3
当前线程名:thread-1,循环的次数:4
当前线程名:thread-2,循环的次数:4
当前线程名:thread-1,循环的次数:5
当前线程名:thread-2,循环的次数:5
当前线程名:thread-1,循环的次数:6
当前线程名:thread-2,循环的次数:6
当前线程名:thread-1,循环的次数:7
当前线程名:thread-2,循环的次数:7
当前线程名:thread-1,循环的次数:8
当前线程名:thread-2,循环的次数:8
当前线程名:thread-1,循环的次数:9
当前线程名:thread-2,循环的次数:9
Process finished with exit code 0
实现Runnable接口
为了解决单继承的局限性,建议实现Runnable接口
Runnable是可以共享数据的,多个Thread可以同时加载一个Runnable,当各自Thread获得CPU时间片的时候开始运行Runnable,Runnable里面的资源是被共享的,所以使用Runnable更加的灵活
注意 :需要解决共享之后产生的资源竞争问题
自定义类实现Runnable接口:
package com.ahut.thread;
/**
* @author cheng
* @className: RunnableImpl
* @description:
* @dateTime 2018/6/4 16:14
*/
public class RunnableImpl implements Runnable {
private String threadName;
RunnableImpl(String threadName) {
this.threadName = threadName;
}
/**
* @description:
* @author cheng
* @dateTime 2018/6/4 15:43
*/
@Override
public void run() {
for (int i = 0; i < 10; i++) {
System.out.println("当前线程名:" + threadName + ",循环的次数:" + i);
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
测试:
package com.ahut.thread;
import java.util.concurrent.Callable;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.FutureTask;
/**
* @author cheng
* @className: ThreadMain
* @description:
* @dateTime 2018/6/4 15:46
*/
public class ThreadMain {
/**
* @description: 主函数
* @author cheng
* @dateTime 2018/6/4 15:46
*/
public static void main(String[] args){
// 创建任务
RunnableImpl runnableImpl1 = new RunnableImpl("runnable-1");
RunnableImpl runnableImpl2 = new RunnableImpl("runnable-2");
// 创建线程
Thread thread1 = new Thread(runnableImpl1);
Thread thread2 = new Thread(runnableImpl2);
// 启动线程
thread1.start();
thread2.start();
}
}
运行结果:
"C:\Program Files\Java\jdk1.8.0_131\bin\java" "-javaagent:F:\IDEA\IntelliJ IDEA 2017.3.4\lib\idea_rt.jar=57593:F:\IDEA\IntelliJ IDEA 2017.3.4\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;D:\IDEA workspace\ahut-dubbo\ahut-redis\target\test-classes;D:\IDEA workspace\ahut-dubbo\ahut-redis\target\classes;C:\Users\rick\.m2\repository\redis\clients\jedis\2.9.0\jedis-2.9.0.jar;C:\Users\rick\.m2\repository\org\apache\commons\commons-pool2\2.5.0\commons-pool2-2.5.0.jar;C:\Users\rick\.m2\repository\org\springframework\boot\spring-boot-starter-web\2.0.2.RELEASE\spring-boot-starter-web-2.0.2.RELEASE.jar;C:\Users\rick\.m2\repository\org\springframework\boot\spring-boot-starter\2.0.2.RELEASE\spring-boot-starter-2.0.2.RELEASE.jar;C:\Users\rick\.m2\repository\org\springframework\boot\spring-boot\2.0.2.RELEASE\spring-boot-2.0.2.RELEASE.jar;C:\Users\rick\.m2\repository\org\springframework\boot\spring-boot-autoconfigure\2.0.2.RELEASE\spring-boot-autoconfigure-2.0.2.RELEASE.jar;C:\Users\rick\.m2\repository\org\springframework\boot\spring-boot-starter-logging\2.0.2.RELEASE\spring-boot-starter-logging-2.0.2.RELEASE.jar;C:\Users\rick\.m2\repository\ch\qos\logback\logback-classic\1.2.3\logback-classic-1.2.3.jar;C:\Users\rick\.m2\repository\ch\qos\logback\logback-core\1.2.3\logback-core-1.2.3.jar;C:\Users\rick\.m2\repository\org\apache\logging\log4j\log4j-to-slf4j\2.10.0\log4j-to-slf4j-2.10.0.jar;C:\Users\rick\.m2\repository\org\apache\logging\log4j\log4j-api\2.10.0\log4j-api-2.10.0.jar;C:\Users\rick\.m2\repository\org\slf4j\jul-to-slf4j\1.7.25\jul-to-slf4j-1.7.25.jar;C:\Users\rick\.m2\repository\javax\annotation\javax.annotation-api\1.3.2\javax.annotation-api-1.3.2.jar;C:\Users\rick\.m2\repository\org\yaml\snakeyaml\1.19\snakeyaml-1.19.jar;C:\Users\rick\.m2\repository\org\springframework\boot\spring-boot-starter-json\2.0.2.RELEASE\spring-boot-starter-json-2.0.2.RELEASE.jar;C:\Users\rick\.m2\repository\com\fasterxml\jackson\core\jackson-databind\2.9.5\jackson-databind-2.9.5.jar;C:\Users\rick\.m2\repository\com\fasterxml\jackson\core\jackson-annotations\2.9.0\jackson-annotations-2.9.0.jar;C:\Users\rick\.m2\repository\com\fasterxml\jackson\core\jackson-core\2.9.5\jackson-core-2.9.5.jar;C:\Users\rick\.m2\repository\com\fasterxml\jackson\datatype\jackson-datatype-jdk8\2.9.5\jackson-datatype-jdk8-2.9.5.jar;C:\Users\rick\.m2\repository\com\fasterxml\jackson\datatype\jackson-datatype-jsr310\2.9.5\jackson-datatype-jsr310-2.9.5.jar;C:\Users\rick\.m2\repository\com\fasterxml\jackson\module\jackson-module-parameter-names\2.9.5\jackson-module-parameter-names-2.9.5.jar;C:\Users\rick\.m2\repository\org\springframework\boot\spring-boot-starter-tomcat\2.0.2.RELEASE\spring-boot-starter-tomcat-2.0.2.RELEASE.jar;C:\Users\rick\.m2\repository\org\apache\tomcat\embed\tomcat-embed-core\8.5.31\tomcat-embed-core-8.5.31.jar;C:\Users\rick\.m2\repository\org\apache\tomcat\embed\tomcat-embed-el\8.5.31\tomcat-embed-el-8.5.31.jar;C:\Users\rick\.m2\repository\org\apache\tomcat\embed\tomcat-embed-websocket\8.5.31\tomcat-embed-websocket-8.5.31.jar;C:\Users\rick\.m2\repository\org\hibernate\validator\hibernate-validator\6.0.9.Final\hibernate-validator-6.0.9.Final.jar;C:\Users\rick\.m2\repository\javax\validation\validation-api\2.0.1.Final\validation-api-2.0.1.Final.jar;C:\Users\rick\.m2\repository\org\jboss\logging\jboss-logging\3.3.2.Final\jboss-logging-3.3.2.Final.jar;C:\Users\rick\.m2\repository\com\fasterxml\classmate\1.3.4\classmate-1.3.4.jar;C:\Users\rick\.m2\repository\org\springframework\spring-web\5.0.6.RELEASE\spring-web-5.0.6.RELEASE.jar;C:\Users\rick\.m2\repository\org\springframework\spring-beans\5.0.6.RELEASE\spring-beans-5.0.6.RELEASE.jar;C:\Users\rick\.m2\repository\org\springframework\spring-webmvc\5.0.6.RELEASE\spring-webmvc-5.0.6.RELEASE.jar;C:\Users\rick\.m2\repository\org\springframework\spring-aop\5.0.6.RELEASE\spring-aop-5.0.6.RELEASE.jar;C:\Users\rick\.m2\repository\org\springframework\spring-context\5.0.6.RELEASE\spring-context-5.0.6.RELEASE.jar;C:\Users\rick\.m2\repository\org\springframework\spring-expression\5.0.6.RELEASE\spring-expression-5.0.6.RELEASE.jar;C:\Users\rick\.m2\repository\org\springframework\boot\spring-boot-starter-test\2.0.2.RELEASE\spring-boot-starter-test-2.0.2.RELEASE.jar;C:\Users\rick\.m2\repository\org\springframework\boot\spring-boot-test\2.0.2.RELEASE\spring-boot-test-2.0.2.RELEASE.jar;C:\Users\rick\.m2\repository\org\springframework\boot\spring-boot-test-autoconfigure\2.0.2.RELEASE\spring-boot-test-autoconfigure-2.0.2.RELEASE.jar;C:\Users\rick\.m2\repository\com\jayway\jsonpath\json-path\2.4.0\json-path-2.4.0.jar;C:\Users\rick\.m2\repository\net\minidev\json-smart\2.3\json-smart-2.3.jar;C:\Users\rick\.m2\repository\net\minidev\accessors-smart\1.2\accessors-smart-1.2.jar;C:\Users\rick\.m2\repository\org\ow2\asm\asm\5.0.4\asm-5.0.4.jar;C:\Users\rick\.m2\repository\org\slf4j\slf4j-api\1.7.25\slf4j-api-1.7.25.jar;C:\Users\rick\.m2\repository\junit\junit\4.12\junit-4.12.jar;C:\Users\rick\.m2\repository\org\assertj\assertj-core\3.9.1\assertj-core-3.9.1.jar;C:\Users\rick\.m2\repository\org\mockito\mockito-core\2.15.0\mockito-core-2.15.0.jar;C:\Users\rick\.m2\repository\net\bytebuddy\byte-buddy\1.7.11\byte-buddy-1.7.11.jar;C:\Users\rick\.m2\repository\net\bytebuddy\byte-buddy-agent\1.7.11\byte-buddy-agent-1.7.11.jar;C:\Users\rick\.m2\repository\org\objenesis\objenesis\2.6\objenesis-2.6.jar;C:\Users\rick\.m2\repository\org\hamcrest\hamcrest-core\1.3\hamcrest-core-1.3.jar;C:\Users\rick\.m2\repository\org\hamcrest\hamcrest-library\1.3\hamcrest-library-1.3.jar;C:\Users\rick\.m2\repository\org\skyscreamer\jsonassert\1.5.0\jsonassert-1.5.0.jar;C:\Users\rick\.m2\repository\com\vaadin\external\google\android-json\0.0.20131108.vaadin1\android-json-0.0.20131108.vaadin1.jar;C:\Users\rick\.m2\repository\org\springframework\spring-core\5.0.6.RELEASE\spring-core-5.0.6.RELEASE.jar;C:\Users\rick\.m2\repository\org\springframework\spring-jcl\5.0.6.RELEASE\spring-jcl-5.0.6.RELEASE.jar;C:\Users\rick\.m2\repository\org\springframework\spring-test\5.0.6.RELEASE\spring-test-5.0.6.RELEASE.jar;C:\Users\rick\.m2\repository\org\xmlunit\xmlunit-core\2.5.1\xmlunit-core-2.5.1.jar" com.ahut.thread.ThreadMain
当前线程名:runnable-1,循环的次数:0
当前线程名:runnable-2,循环的次数:0
当前线程名:runnable-2,循环的次数:1
当前线程名:runnable-1,循环的次数:1
当前线程名:runnable-2,循环的次数:2
当前线程名:runnable-1,循环的次数:2
当前线程名:runnable-1,循环的次数:3
当前线程名:runnable-2,循环的次数:3
当前线程名:runnable-2,循环的次数:4
当前线程名:runnable-1,循环的次数:4
当前线程名:runnable-2,循环的次数:5
当前线程名:runnable-1,循环的次数:5
当前线程名:runnable-2,循环的次数:6
当前线程名:runnable-1,循环的次数:6
当前线程名:runnable-2,循环的次数:7
当前线程名:runnable-1,循环的次数:7
当前线程名:runnable-2,循环的次数:8
当前线程名:runnable-1,循环的次数:8
当前线程名:runnable-2,循环的次数:9
当前线程名:runnable-1,循环的次数:9
Process finished with exit code 0
实现Callable接口
Runnable是执行工作的独立任务,但是它不返回任何值。如果你希望任务在完成的能返回一个值,那么可以实现Callable接口而不是Runnable接口。
在Java SE5中引入的Callable是一种具有类型参数的泛型,它的参数类型表示的是从方法call()(不是run())中返回的值。
自定义类实现Callable接口:
package com.ahut.thread;
import java.util.concurrent.Callable;
/**
* @author cheng
* @className: CallableImpl
* @description:
* @dateTime 2018/6/4 16:15
*/
public class CallableImpl implements Callable<Boolean> {
private String threadName;
CallableImpl(String threadName) {
this.threadName = threadName;
}
/**
* @description:
* @author cheng
* @dateTime 2018/6/4 16:53
*/
@Override
public Boolean call() throws Exception {
for (int i = 0; i < 10; i++) {
System.out.println("当前线程名:" + threadName + ",循环的次数:" + i);
Thread.sleep(500);
}
return true;
}
}
测试:
package com.ahut.thread;
import java.util.concurrent.Callable;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.FutureTask;
/**
* @author cheng
* @className: ThreadMain
* @description:
* @dateTime 2018/6/4 15:46
*/
public class ThreadMain {
/**
* @description: 主函数
* @author cheng
* @dateTime 2018/6/4 15:46
*/
public static void main(String[] args) throws ExecutionException, InterruptedException {
// 创建任务
CallableImpl callable1 = new CallableImpl("callable-1");
CallableImpl callable2 = new CallableImpl("callable-2");
// 获取返回结果
FutureTask<Boolean> futureTask1 = new FutureTask<>(callable1);
FutureTask<Boolean> futureTask2 = new FutureTask<>(callable2);
// 创建线程
new Thread(futureTask1).start();
new Thread(futureTask2).start();
long startTime1 = System.currentTimeMillis();
boolean flag1 = futureTask1.get();
System.out.println("返回结果:" + flag1);
long endTime1 = System.currentTimeMillis();
System.out.println("阻塞时间:" + (endTime1 - startTime1));
long startTime2 = System.currentTimeMillis();
boolean flag2 = futureTask2.get();
System.out.println("返回结果:" + flag2);
long endTime2 = System.currentTimeMillis();
System.out.println("阻塞时间:" + (endTime2 - startTime2));
}
}
运行结果:
"C:\Program Files\Java\jdk1.8.0_131\bin\java" "-javaagent:F:\IDEA\IntelliJ IDEA 2017.3.4\lib\idea_rt.jar=57627:F:\IDEA\IntelliJ IDEA 2017.3.4\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;D:\IDEA workspace\ahut-dubbo\ahut-redis\target\test-classes;D:\IDEA workspace\ahut-dubbo\ahut-redis\target\classes;C:\Users\rick\.m2\repository\redis\clients\jedis\2.9.0\jedis-2.9.0.jar;C:\Users\rick\.m2\repository\org\apache\commons\commons-pool2\2.5.0\commons-pool2-2.5.0.jar;C:\Users\rick\.m2\repository\org\springframework\boot\spring-boot-starter-web\2.0.2.RELEASE\spring-boot-starter-web-2.0.2.RELEASE.jar;C:\Users\rick\.m2\repository\org\springframework\boot\spring-boot-starter\2.0.2.RELEASE\spring-boot-starter-2.0.2.RELEASE.jar;C:\Users\rick\.m2\repository\org\springframework\boot\spring-boot\2.0.2.RELEASE\spring-boot-2.0.2.RELEASE.jar;C:\Users\rick\.m2\repository\org\springframework\boot\spring-boot-autoconfigure\2.0.2.RELEASE\spring-boot-autoconfigure-2.0.2.RELEASE.jar;C:\Users\rick\.m2\repository\org\springframework\boot\spring-boot-starter-logging\2.0.2.RELEASE\spring-boot-starter-logging-2.0.2.RELEASE.jar;C:\Users\rick\.m2\repository\ch\qos\logback\logback-classic\1.2.3\logback-classic-1.2.3.jar;C:\Users\rick\.m2\repository\ch\qos\logback\logback-core\1.2.3\logback-core-1.2.3.jar;C:\Users\rick\.m2\repository\org\apache\logging\log4j\log4j-to-slf4j\2.10.0\log4j-to-slf4j-2.10.0.jar;C:\Users\rick\.m2\repository\org\apache\logging\log4j\log4j-api\2.10.0\log4j-api-2.10.0.jar;C:\Users\rick\.m2\repository\org\slf4j\jul-to-slf4j\1.7.25\jul-to-slf4j-1.7.25.jar;C:\Users\rick\.m2\repository\javax\annotation\javax.annotation-api\1.3.2\javax.annotation-api-1.3.2.jar;C:\Users\rick\.m2\repository\org\yaml\snakeyaml\1.19\snakeyaml-1.19.jar;C:\Users\rick\.m2\repository\org\springframework\boot\spring-boot-starter-json\2.0.2.RELEASE\spring-boot-starter-json-2.0.2.RELEASE.jar;C:\Users\rick\.m2\repository\com\fasterxml\jackson\core\jackson-databind\2.9.5\jackson-databind-2.9.5.jar;C:\Users\rick\.m2\repository\com\fasterxml\jackson\core\jackson-annotations\2.9.0\jackson-annotations-2.9.0.jar;C:\Users\rick\.m2\repository\com\fasterxml\jackson\core\jackson-core\2.9.5\jackson-core-2.9.5.jar;C:\Users\rick\.m2\repository\com\fasterxml\jackson\datatype\jackson-datatype-jdk8\2.9.5\jackson-datatype-jdk8-2.9.5.jar;C:\Users\rick\.m2\repository\com\fasterxml\jackson\datatype\jackson-datatype-jsr310\2.9.5\jackson-datatype-jsr310-2.9.5.jar;C:\Users\rick\.m2\repository\com\fasterxml\jackson\module\jackson-module-parameter-names\2.9.5\jackson-module-parameter-names-2.9.5.jar;C:\Users\rick\.m2\repository\org\springframework\boot\spring-boot-starter-tomcat\2.0.2.RELEASE\spring-boot-starter-tomcat-2.0.2.RELEASE.jar;C:\Users\rick\.m2\repository\org\apache\tomcat\embed\tomcat-embed-core\8.5.31\tomcat-embed-core-8.5.31.jar;C:\Users\rick\.m2\repository\org\apache\tomcat\embed\tomcat-embed-el\8.5.31\tomcat-embed-el-8.5.31.jar;C:\Users\rick\.m2\repository\org\apache\tomcat\embed\tomcat-embed-websocket\8.5.31\tomcat-embed-websocket-8.5.31.jar;C:\Users\rick\.m2\repository\org\hibernate\validator\hibernate-validator\6.0.9.Final\hibernate-validator-6.0.9.Final.jar;C:\Users\rick\.m2\repository\javax\validation\validation-api\2.0.1.Final\validation-api-2.0.1.Final.jar;C:\Users\rick\.m2\repository\org\jboss\logging\jboss-logging\3.3.2.Final\jboss-logging-3.3.2.Final.jar;C:\Users\rick\.m2\repository\com\fasterxml\classmate\1.3.4\classmate-1.3.4.jar;C:\Users\rick\.m2\repository\org\springframework\spring-web\5.0.6.RELEASE\spring-web-5.0.6.RELEASE.jar;C:\Users\rick\.m2\repository\org\springframework\spring-beans\5.0.6.RELEASE\spring-beans-5.0.6.RELEASE.jar;C:\Users\rick\.m2\repository\org\springframework\spring-webmvc\5.0.6.RELEASE\spring-webmvc-5.0.6.RELEASE.jar;C:\Users\rick\.m2\repository\org\springframework\spring-aop\5.0.6.RELEASE\spring-aop-5.0.6.RELEASE.jar;C:\Users\rick\.m2\repository\org\springframework\spring-context\5.0.6.RELEASE\spring-context-5.0.6.RELEASE.jar;C:\Users\rick\.m2\repository\org\springframework\spring-expression\5.0.6.RELEASE\spring-expression-5.0.6.RELEASE.jar;C:\Users\rick\.m2\repository\org\springframework\boot\spring-boot-starter-test\2.0.2.RELEASE\spring-boot-starter-test-2.0.2.RELEASE.jar;C:\Users\rick\.m2\repository\org\springframework\boot\spring-boot-test\2.0.2.RELEASE\spring-boot-test-2.0.2.RELEASE.jar;C:\Users\rick\.m2\repository\org\springframework\boot\spring-boot-test-autoconfigure\2.0.2.RELEASE\spring-boot-test-autoconfigure-2.0.2.RELEASE.jar;C:\Users\rick\.m2\repository\com\jayway\jsonpath\json-path\2.4.0\json-path-2.4.0.jar;C:\Users\rick\.m2\repository\net\minidev\json-smart\2.3\json-smart-2.3.jar;C:\Users\rick\.m2\repository\net\minidev\accessors-smart\1.2\accessors-smart-1.2.jar;C:\Users\rick\.m2\repository\org\ow2\asm\asm\5.0.4\asm-5.0.4.jar;C:\Users\rick\.m2\repository\org\slf4j\slf4j-api\1.7.25\slf4j-api-1.7.25.jar;C:\Users\rick\.m2\repository\junit\junit\4.12\junit-4.12.jar;C:\Users\rick\.m2\repository\org\assertj\assertj-core\3.9.1\assertj-core-3.9.1.jar;C:\Users\rick\.m2\repository\org\mockito\mockito-core\2.15.0\mockito-core-2.15.0.jar;C:\Users\rick\.m2\repository\net\bytebuddy\byte-buddy\1.7.11\byte-buddy-1.7.11.jar;C:\Users\rick\.m2\repository\net\bytebuddy\byte-buddy-agent\1.7.11\byte-buddy-agent-1.7.11.jar;C:\Users\rick\.m2\repository\org\objenesis\objenesis\2.6\objenesis-2.6.jar;C:\Users\rick\.m2\repository\org\hamcrest\hamcrest-core\1.3\hamcrest-core-1.3.jar;C:\Users\rick\.m2\repository\org\hamcrest\hamcrest-library\1.3\hamcrest-library-1.3.jar;C:\Users\rick\.m2\repository\org\skyscreamer\jsonassert\1.5.0\jsonassert-1.5.0.jar;C:\Users\rick\.m2\repository\com\vaadin\external\google\android-json\0.0.20131108.vaadin1\android-json-0.0.20131108.vaadin1.jar;C:\Users\rick\.m2\repository\org\springframework\spring-core\5.0.6.RELEASE\spring-core-5.0.6.RELEASE.jar;C:\Users\rick\.m2\repository\org\springframework\spring-jcl\5.0.6.RELEASE\spring-jcl-5.0.6.RELEASE.jar;C:\Users\rick\.m2\repository\org\springframework\spring-test\5.0.6.RELEASE\spring-test-5.0.6.RELEASE.jar;C:\Users\rick\.m2\repository\org\xmlunit\xmlunit-core\2.5.1\xmlunit-core-2.5.1.jar" com.ahut.thread.ThreadMain
当前线程名:callable-1,循环的次数:0
当前线程名:callable-2,循环的次数:0
当前线程名:callable-2,循环的次数:1
当前线程名:callable-1,循环的次数:1
当前线程名:callable-2,循环的次数:2
当前线程名:callable-1,循环的次数:2
当前线程名:callable-1,循环的次数:3
当前线程名:callable-2,循环的次数:3
当前线程名:callable-1,循环的次数:4
当前线程名:callable-2,循环的次数:4
当前线程名:callable-2,循环的次数:5
当前线程名:callable-1,循环的次数:5
当前线程名:callable-2,循环的次数:6
当前线程名:callable-1,循环的次数:6
当前线程名:callable-2,循环的次数:7
当前线程名:callable-1,循环的次数:7
当前线程名:callable-1,循环的次数:8
当前线程名:callable-2,循环的次数:8
当前线程名:callable-1,循环的次数:9
当前线程名:callable-2,循环的次数:9
返回结果:true
阻塞时间:5051
返回结果:true
阻塞时间:0
Process finished with exit code 0
三种方法的比较
实现Runnable接口相比继承Thread类有如下优势
- 可以避免由于Java的单继承特性而带来的局限
- 增强程序的健壮性,代码能够被多个线程共享,代码与数据是独立的
- 适合多个相同程序代码的线程去处理同一资源的情况
- 线程池只能放入实现Runable或Callable类线程,不能直接放入继承Thread的类
实现Runnable接口和实现Callable接口的区别
- Runnable是自从java1.1就有了,而Callable是1.5之后才加上去的
- 实现Callable接口的任务线程能返回执行结果,而实现Runnable接口的任务线程不能返回结果
- Callable接口的call()方法允许抛出异常,而Runnable接口的run()方法的异常只能在内部消化,不能继续上抛
- 加入线程池运行,Runnable使用ExecutorService的execute方法,Callable使用submit方法
- Callable接口支持返回执行结果,此时需要调用FutureTask.get()方法实现,此方法会阻塞主线程直到获取返回结果,当不调用此方法时,主线程不会阻塞