多线程的创建与Thread的常用方法

简介: 多线程的创建与Thread的常用方法

1.多线程的创建

Thread类

Java是通过java.lang.Thread类来代表线程的。

按照面向对象的思想,Thread类提供了实现多线程的方式。

1.1方式一:继承Thread类

多线程的实现方案一:继承Thread类

① 定义一个子类MyThread继承线程类java.lang.Thread,重写run()方法。

② 创建MyThread类的对象。

③ 调用线程对象的start()方法启动线程(启动后还是执行run方法的)。

方式一优缺点:

优点:编码简单。

缺点:线程类已经继承Thread,无法继承其他类,不利于扩展。

示例代码如下:

publicclassThreadDemo1 {
publicstaticvoidmain(String[] args) {
// 3.实例化线程对象Threadt=newMyThread();
// 4.调用start方法启动子线程(执行run方法)t.start();
for (inti=0; i<5; i++) {
System.out.println("主线程执行输出:"+i);
        }
    }
}
/*** 1.自定义一个线程类继承Thread类*/classMyThreadextendsThread {
/*** 2.重写run方法,其中是此线程要做的工作*/@Overridepublicvoidrun() {
for (inti=0; i<5; i++) {
System.out.println("子线程执行输出:"+i);
        }
    }
}

注:main方法中不是直接调用run方法,而是调用start方法启动线程中的run方法。

直接调用run方法会当成普通方法执行,此时相当于还是单线程执行。

只有调用start方法才是启动一个新的线程执行。

注意将主线程任务放在子线程任务之后,否则主线程执行完毕后再执行子线程,相当于是一个单线程的效果。

1.2方式二:实现Runnable接口

多线程的实现方案二:实现Runnable接口

① 定义一个线程任务类MyRunnable实现Runnable接口,重写run()方法。

② 创建MyRunnable任务对象。

③ 把MyRunnable任务对象交给Thread处理。

④ 调用线程对象的start()方法启动线程。

Thread类构造器

方法名

说明

public Thread(String name)

可以为当前线程指定名称

public Thread(Runnable target)

封装Runnable对象成为线程对象

public Thread(Runnable target ,String name )

封装Runnable对象成为线程对象,并指定线程名称

 

方式二优缺点:

优点:线程任务类只是实现接口,可以继续继承类和实现接口,扩展性强。

缺点:编程多一层对象包装,如果线程有执行结果是不可以直接返回的。

示例代码如下:

publicclassThreadDemo2 {
publicstaticvoidmain(String[] args) {
// 3.创建一个任务对象Runnabletarget=newMyRunnable();
// 4.把任务对象交给Thread处理Threadt=newThread(target);
// 5.启动线程t.start();
for (inti=0; i<5; i++) {
System.out.println("主线程执行:"+i);
        }
    }
}
/*** 定义一个线程任务类,实现Runnable接口*/classMyRunnableimplementsRunnable {
/*** 重写run方法,定义线程的执行任务*/@Overridepublicvoidrun() {
for (inti=0; i<5; i++) {
System.out.println("子线程执行:"+i);
        }
    }
}

多线程的实现方案二:实现Runnable接口(匿名内部类形式)

① 可以创建Runnable的匿名内部类对象。

② 交给Thread处理。

③ 调用线程对象的start()启动线程。

示例代码如下:

publicclassThreadDemo2Other {
publicstaticvoidmain(String[] args) {
newThread(() -> {
for (inti=0; i<5; i++) {
System.out.println("子线程执行:"+i);
            }
        }).start();
for (inti=0; i<5; i++) {
System.out.println("主线程执行:"+i);
        }
    }
}

1.3方式三:JDK 5.0新增:实现Callable接口

前2种线程创建方式都存在一个问题:他们重写的run方法均不能直接返回结果,不适合需要返回线程执行结果的业务场景。

怎么解决这个问题呢?JDK 5.0提供了Callable和FutureTask来实现,这种方式的优点是可以得到线程执行的结果

多线程的实现方案三:利用Callable、FutureTask接口实现

①得到任务对象

1)定义类实现Callable接口,重写call方法,封装要做的事情。

2)用FutureTask把Callable对象封装成线程任务对象。

②把线程任务对象交给Thread处理。

③调用Thread的start方法启动线程,执行任务

④线程执行完毕后、通过FutureTask的get方法去获取任务执行的结果。

FutureTask的常用API

方法名

说明

public FutureTask<>(Callable call)

把Callable对象封装成FutureTask对象

(需要声明任务对象返回值的泛型)

public V get() throws Exception

获取线程执行call方法返回的结果

 

示例代码如下:

publicclassThreadDemo3 {
publicstaticvoidmain(String[] args) {
// 3.创建Callable任务对象Callable<String>call=newMyCallable(10);
// 4.将Callable任务对象交给FutureTask对象,封装为真正的任务对象/*FutureTask对象的作用:实现了Runnable接口,可以交给Thread对象处理可以在线程执行完毕之后通过调用其get方法获取线程执行完毕的返回值*/FutureTask<String>f=newFutureTask(call);
// 5.将任务对象交给Thread处理Threadt=newThread(f);
// 6.启动线程t.start();
Callable<String>call2=newMyCallable(20);
FutureTask<String>f2=newFutureTask(call2);
Threadt2=newThread(f2);
t2.start();
try {
// 若任务没有执行完毕,则代码会在这里等待,直至线程执行完毕,再执行get方法,获取返回值Stringrs=f.get();
System.out.println("第1个结果:"+rs);
        } catch (Exceptione) {
e.printStackTrace();
        }
try {
Stringrs2=f2.get();
System.out.println("第2个结果:"+rs2);
        } catch (Exceptione) {
e.printStackTrace();
        }
    }
}
/*** 1.定义一个任务类,实现Callable接口,需要声明泛型,表明返回值类型*/classMyCallableimplementsCallable<String> {
privateintn;
publicMyCallable(intn) {
this.n=n;
    }
/*** 2.重写call方法(任务方法)   此处为求和方法** @return* @throws Exception*/@OverridepublicStringcall() throwsException {
intsum=0;
for (inti=1; i<=n; i++) {
sum+=i;
        }
return"子线程执行结果"+sum;
    }
}

注:若任务没有执行完毕,则代码会在获取返回值的get方法处等待,直至线程执行完毕,再执行get方法,获取返回值。

2.Thread的常用方法

Thread类常用方法

方法名

说明

String getName ()

获取当前线程的名称,默认线程名称是Thread-索引

void setName (String name)

将此线程的名称更改为指定的名称,

通过构造器也可以设置线程名称

public static Thread currentThread()

返回对当前正在执行的线程对象的引用

public static void sleep(long time)

让当前线程休眠指定的时间后再继续执行,单位为毫秒

public void run()

线程任务方法

public void start()

线程启动方法

 

示例代码如下:

自定义MyThread类

publicclassMyThreadextendsThread {
publicMyThread() {
    }
publicMyThread(Stringname) {
// 为当前线程对象设置名称,交给父类有参构造器初始化super(name);
    }
@Overridepublicvoidrun() {
for (inti=0; i<5; i++) {
System.out.println(Thread.currentThread().getName() +"输出:"+i);
        }
    }
}
测试类publicclassThreadDemo1 {
publicstaticvoidmain(String[] args) throwsInterruptedException {
Threadt=newMyThread("1号线程");
t.start();
Threadt2=newMyThread("2号线程");
t2.start();
// 哪个线程执行它,它就得到哪个线程对象(当前线程对象)Threadm=Thread.currentThread();
System.out.println(m.getName()); // 主线程名称为"main"for (inti=0; i<5; i++) {
if (i==2) {
// 让线程休眠3sThread.sleep(3000);
            }
System.out.println("main线程输出:"+i);
        }
    }
}

程序运行结果如下:

main

main线程输出:0

main线程输出:1

1号线程输出:0

1号线程输出:1

1号线程输出:2

1号线程输出:3

1号线程输出:4

2号线程输出:0

2号线程输出:1

2号线程输出:2

2号线程输出:3

2号线程输出:4

main线程输出:2

main线程输出:3

main线程输出:4

相关文章
|
28天前
|
存储 Oracle Java
|
3月前
|
Java
创建线程的方法
Java中实现多线程有四种方式:1. 继承Thread类,简单但占用继承机会,耦合度高;2. 实现Runnable接口,推荐方式,任务与线程解耦,支持Lambda;3. 实现Callable接口配合FutureTask,可获取返回值和异常;4. 使用线程池(ExecutorService),企业推荐,管理线程生命周期,提升性能,支持多种线程池类型。
75 1
|
4月前
|
Java 数据挖掘 调度
Java 多线程创建零基础入门新手指南:从零开始全面学习多线程创建方法
本文从零基础角度出发,深入浅出地讲解Java多线程的创建方式。内容涵盖继承`Thread`类、实现`Runnable`接口、使用`Callable`和`Future`接口以及线程池的创建与管理等核心知识点。通过代码示例与应用场景分析,帮助读者理解每种方式的特点及适用场景,理论结合实践,轻松掌握Java多线程编程 essentials。
270 5
|
5月前
|
Arthas 监控 Java
Arthas thread(查看当前JVM的线程堆栈信息)
Arthas thread(查看当前JVM的线程堆栈信息)
866 10
|
11月前
|
Java C# Python
线程等待(Thread Sleep)
线程等待是多线程编程中的一种同步机制,通过暂停当前线程的执行,让出CPU时间给其他线程。常用于需要程序暂停或等待其他线程完成操作的场景。不同语言中实现方式各异,如Java的`Thread.sleep(1000)`、C#的`Thread.Sleep(1000)`和Python的`time.sleep(1)`。使用时需注意避免死锁,并考虑其对程序响应性的影响。
270 8
|
10月前
|
缓存 安全 Java
【JavaEE】——单例模式引起的多线程安全问题:“饿汉/懒汉”模式,及解决思路和方法(面试高频)
单例模式下,“饿汉模式”,“懒汉模式”,单例模式下引起的线程安全问题,解锁思路和解决方法
|
10月前
|
Java 程序员 调度
【JavaEE】线程创建和终止,Thread类方法,变量捕获(7000字长文)
创建线程的五种方式,Thread常见方法(守护进程.setDaemon() ,isAlive),start和run方法的区别,如何提前终止一个线程,标志位,isinterrupted,变量捕获
|
10月前
|
安全 Java API
【JavaEE】多线程编程引入——认识Thread类
Thread类,Thread中的run方法,在编程中怎么调度多线程
|
12月前
|
Java 开发者
在Java多线程编程中,选择合适的线程创建方法至关重要
【10月更文挑战第20天】在Java多线程编程中,选择合适的线程创建方法至关重要。本文通过案例分析,探讨了继承Thread类和实现Runnable接口两种方法的优缺点及适用场景,帮助开发者做出明智的选择。
112 2
|
12月前
|
Java
在Java多线程编程中,实现Runnable接口通常优于继承Thread类
【10月更文挑战第20天】在Java多线程编程中,实现Runnable接口通常优于继承Thread类。原因包括:1) Java只支持单继承,实现接口不受此限制;2) Runnable接口便于代码复用和线程池管理;3) 分离任务与线程,提高灵活性。因此,实现Runnable接口是更佳选择。
234 2

热门文章

最新文章