【Thread -- 1.1】 实现多线程的正确姿势
一、实现多线程的方法有几种--两种
1、正确方法--Oraclle官方文档--2种
[Oraclle官方文档](Overview (Java Platform SE 8 ) (oracle.com))
-
实现Runnable接口--推荐,优点:
- 代码架构解耦,将具体运行内容和创建线程解耦
- 资源节约 不用每次都创建新线程
- 扩展性 接口能多继承
-
继承Thread类(重写Runnable的run方法)
2.、承Thread
package Thread.createthreads;
/**
* 描述: 继承Thread方式实现线程
*/
public class ThreadStyle extends Thread{
@Override
public void run() {
System.out.println("用Thread类实现线程");
}
public static void main(String[] args) {
new ThreadStyle().start();
}
}
源码分析:
3、实现Runnable接口
package Thread.createthreads;
/**
* 描述: 用实现Runnable接口创建线程
* 优点: 代码架构解耦,将具体运行内容和创建线程解耦
* 资源节约 不用每次都创建新线程
* 扩展性 接口能多继承
*/
public class RunnableStyle{
public static void main(String[] args) {
Thread thread1 = new Thread(new test1());
Thread thread2 = new Thread(new test2());
thread2.start();
thread1.start();
}
}
class test1 implements Runnable{
@Override
public void run() {
for (int i = 0; i < 10; i++) {
System.out.println(Thread.currentThread().getName() + ":");
System.out.println(i);
}
}
}
class test2 implements Runnable{
@Override
public void run() {
for (int i = 10; i < 20; i++) {
System.out.println(Thread.currentThread().getName() + ":");
System.out.println(i);
}
}
}
源码分析:
4、两者比较
run方法:线程中逻辑主要方法。
Runnbale接口:只有一个run方法,即实现run方法。
Thread类:继承了Runnable方法,需要重写run方法。
-----两者都是对run方法进行重写,其实都是Thread类对run进行调用。
/**
* 描述:同时使用两种方法实现线程的方式
*/
public class BothRunnableThread {
public static void main(String[] args) {
//匿名内部类
new Thread(new Runnable() {
@Override
public void run() {
System.out.println("我来自Runnable");
}
}) {
//覆盖了Thread中的run方法
@Override
public void run() {
System.out.println("我来自Thread");
}
}.start();
}
}
结果解释:创建Thread类时,重写了run方法,不会在对target(Runnable)的代码进行执行了。
5、结论
总的来说,线程只有一种创建方式,就是构造Thread类,但是Thread类中的执行方法run有两种构建方式:
- 实现Runnable接口的run方法,并且将实现Runnable的实例传给Thread类
- 继承Thread后重写run方法
二、典型的错误创建观点
1、“线程池”
package Thread.createthreads.wrongs;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
/**
* 线程池创建
* 实际上也是new Thread( Runnable)
*/
public class ThreadPool {
public static void main(String[] args) {
ExecutorService executorService = Executors.newCachedThreadPool();
for (int i = 0; i < 100; i++) {
executorService.submit(new Task());
}
}
}
class Task implements Runnable{
@Override
public void run() {
try {
//休眠
Thread.sleep(500);
} catch (InterruptedException e) {
e.printStackTrace();
}
//打印线程名字
System.out.println(Thread.currentThread().getName());
}
}
实际上也是new Thread 通过Runnable实现。
2、通过Callable和FutureTask创建线程,也算是一种新建线程的方式
实现图,FutureTask也是由Runnable和Thread实现的
3、通过定时器创建也是一种方法
/**
* 描述:定时器创建线程
* 每隔一秒打印当前线程的名字
*/
public class DemoTimmerTask {
public static void main(String[] args) {
Timer timer = new Timer();
timer.scheduleAtFixedRate(new TimerTask() {
@Override
public void run() {
System.out.println(Thread.currentThread().getName());
}
}, 1000, 1000);
}
}
4、匿名内部类实现线程的创建也是一种方法
public class AnonymousInnerClassDemo {
public static void main(String[] args) {
new Thread(){
@Override
public void run() {
System.out.println(Thread.currentThread().getName());
}
}.start();
new Thread(new Runnable() {
@Override
public void run() {
System.out.println(Thread.currentThread().getName());
}
}).start();
}
}
三、Lambad表达式
package Lambad;
@FunctionalInterface
public interface MyFun {
public abstract Integer getValue(Integer i);
}
package Lambad;
import java.util.Comparator;
import java.util.function.Consumer;
/**
* Lambad 基础语法 : 新操作符" -> "
*
* 左侧:参数列表
* 右侧:执行功能(体)
*
* 语法格式一:无参数,无返回值
* () -> do
*
* 语法格式二:一个参数,无返回值
* (x) -> do 一个参数()可去掉
*
*语法格式三: 两个参数,有返回值 且体中有多条语句
* Comparator<Integer> com = (x, y) -> {
* System.out.println("函数式接口");
* return Integer.compare(x,y);
* };
*
*
* Lambad需要“函数式接口”的支持 ,@FunctionalInterface可以检测是否是函数式接口。
* 一个抽象方法
*/
public class Demo01 {
public static void main(String[] args) {
new Demo01().test1();
new Demo01().test2();
A.say();
}
//格式一
public void test1(){
int a = 0;//final
Runnable runnable = new Runnable() {
@Override
public void run() {
System.out.println("one");
}
};
runnable.run();
Runnable lam_runnable = () -> System.out.println("one" + a);
lam_runnable.run();
}
//格式二
public void test2() {
Consumer<String> con = (x) -> System.out.println(x) ;
con.accept("two");
}
//格式三
public void test3(){
Comparator<Integer> com = (x, y) -> Integer.compare(x,y);
}
}
interface A{
public static void say() {
System.out.println("A");
};
}
class B implements A{
public void say(){
System.out.println("B");
}
}
四 、面试常见问题
- 代码架构解耦,将具体运行内容和创建线程解耦
- 资源节约 不用每次都创建新线程
- 扩展性 接口能多继承
标签:Runnable,run,1.1,Thread,void,线程,多线程,public
From: https://www.cnblogs.com/DAIXUM/p/17241661.html