多线程的创建
文章目录
前言
记得好几年前无VIP下载视频的时候感觉有点慢,后来推出了花钱开了个VIP,不光能看很多专享电影,这下载速度也是哐哐的上去了,当时觉得这VIP开得值,现在学了多线程,以及了解了seek,感觉VIP没有那么高 大 上了,就是没VIP的时候,一个工作一个人做,有了VIP之后一个工作多人工作,这效率就提高了非常之多。话不多说,进入今天的主题多线程的建立方法简绍。
一、线程的创建概述
Runnable 接口用于定义线程的执行体,Runnable 接口仅仅有一个run方法。Thread实现了Runnable接口,但是它的run方法没有实现任何东西,需要在Thead子类中实现线程执行体。
在Java中创建线程的常用方式如下:
1,继承Thread并重写run()
2、实现Runnable接口
3、实现Callable接口
二、Thread创建线程
1.创建步骤
1、定义子类继承自Thread并重写run方法
2、创建子类实例
3、start方法启动线程
2.代码实现
代码如下(第一个线程):
public class MyThread1 extends Thread{
@Override
public void run() { // 重写Thread的run方法
String name1 = Thread.currentThread().getName();// 使用Thread.currentThread()自带的getName()
for(int i = 0;i<50;i++) { //建立一个测试用的for循环
System.out.println(name1+"打印"+i); // 输出
}
}
}
代码如下(第二个线程):
public class MyThread2 extends Thread{
@Override
public void run() {
String name2 = Thread.currentThread().getName();
for(int j = 0;j<50;j++) {
System.out.println(name2+"打印"+j);
}
}
}
代码如下(测试):
public class Demo02 {
public static void main(String[] args) {
MyThread1 thread01 = new MyThread1();// 创建一个MyThread1()对象
thread01.start();// 启动线程1
MyThread2 thread02 = new MyThread2();// 创建一个MyThread2()对象
thread02.start();// 启动线程2
}
}
代码如下(输出):
Thread-0打印0
Thread-0打印1
Thread-0打印2
Thread-0打印3
Thread-0打印4
Thread-0打印5
Thread-0打印6
Thread-0打印7
Thread-0打印8
Thread-0打印9
Thread-0打印10
Thread-0打印11
Thread-0打印12
Thread-0打印13
Thread-0打印14
Thread-0打印15
Thread-0打印16
Thread-0打印17
Thread-0打印18
Thread-0打印19
Thread-0打印20
Thread-0打印21
Thread-0打印22
Thread-0打印23
Thread-0打印24
Thread-0打印25
Thread-0打印26
Thread-0打印27
Thread-0打印28
Thread-0打印29
Thread-0打印30
Thread-0打印31
Thread-1打印0
Thread-0打印32
Thread-1打印1
Thread-0打印33
Thread-1打印2
Thread-0打印34
Thread-1打印3
Thread-1打印4
Thread-1打印5
Thread-1打印6
Thread-1打印7
Thread-1打印8
Thread-1打印9
Thread-1打印10
Thread-1打印11
Thread-1打印12
Thread-1打印13
Thread-1打印14
Thread-1打印15
Thread-1打印16
Thread-1打印17
Thread-1打印18
Thread-1打印19
Thread-1打印20
Thread-1打印21
Thread-1打印22
Thread-1打印23
Thread-1打印24
Thread-1打印25
Thread-1打印26
Thread-1打印27
Thread-1打印28
Thread-1打印29
Thread-1打印30
Thread-1打印31
Thread-1打印32
Thread-1打印33
Thread-1打印34
Thread-1打印35
Thread-1打印36
Thread-1打印37
Thread-1打印38
Thread-1打印39
Thread-1打印40
Thread-1打印41
Thread-1打印42
Thread-1打印43
Thread-1打印44
Thread-1打印45
Thread-1打印46
Thread-1打印47
Thread-1打印48
Thread-1打印49
Thread-0打印35
Thread-0打印36
Thread-0打印37
Thread-0打印38
Thread-0打印39
Thread-0打印40
Thread-0打印41
Thread-0打印42
Thread-0打印43
Thread-0打印44
Thread-0打印45
Thread-0打印46
Thread-0打印47
Thread-0打印48
Thread-0打印49
三、Runnable创建线程
1.创建步骤
1、定义Runnable接口的实现类,并重写接口的run()方法
2、创建Runnable实现类的对象
3、创建Thread类的对象
4、通过start方法启动线程
2.代码实现
代码如下(第一个线程):
public class MyRunable1 implements Runnable{
@Override
public void run() {// 实现run()方法
String name1 = Thread.currentThread().getName();// 获取线程名
for(int i = 0;i<50;i++) { //建立一个测试用的for循环
System.out.println(name1+"打印"+i); // 输出
}
}
}
代码如下(第二个线程):
public class MyRunable2 implements Runnable{
@Override
public void run() {// 实现run()方法
String name2 = Thread.currentThread().getName();// 获取线程名
for(int i = 0;i<50;i++) { //建立一个测试用的for循环
System.out.println(name2+"打印"+i); // 输出
}
}
}
代码如下(测试):
public class Demo03 {
public static void main(String[] args) {
MyRunable1 myRunable1 = new MyRunable1();// 创建一个MyRunable1对象
Thread thread1 = new Thread(myRunable1); // 创建第一个子线程
thread1.start();// 启动线程1
MyRunable2 myRunable2 = new MyRunable2();// 创建一个MyRunable2对象
Thread thread2 = new Thread(myRunable2); // 创建第二个子线程
thread2.start();// 启动线程2
}
}
代码如下(输出):
Thread-0打印0
Thread-1打印0
Thread-1打印1
Thread-1打印2
Thread-1打印3
Thread-1打印4
Thread-1打印5
Thread-1打印6
Thread-1打印7
Thread-1打印8
Thread-1打印9
Thread-1打印10
Thread-1打印11
Thread-1打印12
Thread-1打印13
Thread-1打印14
Thread-1打印15
Thread-1打印16
Thread-1打印17
Thread-1打印18
Thread-1打印19
Thread-1打印20
Thread-1打印21
Thread-1打印22
Thread-1打印23
Thread-1打印24
Thread-1打印25
Thread-1打印26
Thread-1打印27
Thread-1打印28
Thread-1打印29
Thread-1打印30
Thread-1打印31
Thread-0打印1
Thread-0打印2
Thread-0打印3
Thread-0打印4
Thread-0打印5
Thread-0打印6
Thread-0打印7
Thread-0打印8
Thread-0打印9
Thread-0打印10
Thread-0打印11
Thread-0打印12
Thread-0打印13
Thread-0打印14
Thread-0打印15
Thread-0打印16
Thread-0打印17
Thread-0打印18
Thread-0打印19
Thread-0打印20
Thread-0打印21
Thread-0打印22
Thread-0打印23
Thread-0打印24
Thread-0打印25
Thread-0打印26
Thread-0打印27
Thread-0打印28
Thread-0打印29
Thread-0打印30
Thread-0打印31
Thread-0打印32
Thread-0打印33
Thread-0打印34
Thread-0打印35
Thread-0打印36
Thread-0打印37
Thread-0打印38
Thread-0打印39
Thread-0打印40
Thread-0打印41
Thread-0打印42
Thread-0打印43
Thread-0打印44
Thread-0打印45
Thread-0打印46
Thread-0打印47
Thread-0打印48
Thread-0打印49
Thread-1打印32
Thread-1打印33
Thread-1打印34
Thread-1打印35
Thread-1打印36
Thread-1打印37
Thread-1打印38
Thread-1打印39
Thread-1打印40
Thread-1打印41
Thread-1打印42
Thread-1打印43
Thread-1打印44
Thread-1打印45
Thread-1打印46
Thread-1打印47
Thread-1打印48
Thread-1打印49
四、Callable创建线程
1.Callable创建线程的优势
通过Thread或者Runnable接口实现多线程时需要从写run()方法,但是此方法没有返回值,但是使用Callable这个接口即可创建线程还可以获取返回值。
2.代码实现
代码如下(第一个线程):
import java.util.concurrent.Callable;
public class MyCallable implements Callable<Object>{
@Override
public Object call() throws Exception {
String name1 = Thread.currentThread().getName();// 获取线程名
int i = 0;
while(i<40) {// 测试的while循环
System.out.println(name1+"打印"+i); // 输出
i++;
}
return i;
}
}
代码如下(第二个线程):
import java.util.concurrent.Callable;
public class MyCallable2 implements Callable<Object>{
@Override
public Object call() throws Exception {
String name2 = Thread.currentThread().getName();// 获取线程名
int i = 0;
while(i<40) {// 测试的while循环
System.out.println(name2+"打印"+i); // 输出
i++;
}
return i;
}
}
代码如下(测试):
import java.util.concurrent.ExecutionException;
import java.util.concurrent.FutureTask;
public class Demo04 {
public static void main(String[] args) throws InterruptedException, ExecutionException {
// 创建第一个子线程
MyCallable myCallable1 = new MyCallable();
FutureTask<Object> futureTask1 = new FutureTask<>(myCallable1);
Thread thread1 = new Thread(futureTask1);
thread1.start(); // 启动第一个子线程
// 创建第二个子线程
MyCallable2 myCallable2 = new MyCallable2();
FutureTask<Object> futureTask2 = new FutureTask<>(myCallable2);
Thread thread2 = new Thread(futureTask2);
thread2.start(); // 启动第二个子线程
System.out.println("-----华丽的分割线-------");
// 获取第二个子线程返回的结果
Object result = futureTask2.get();
System.out.println("第二个子线程返回的结果为:"+result);
}
}
代码如下(输出):
Thread-0打印0
Thread-0打印1
Thread-0打印2
Thread-0打印3
Thread-0打印4
Thread-0打印5
-----华丽的分割线-------
Thread-0打印6
Thread-0打印7
Thread-0打印8
Thread-0打印9
Thread-0打印10
Thread-0打印11
Thread-0打印12
Thread-0打印13
Thread-0打印14
Thread-0打印15
Thread-0打印16
Thread-0打印17
Thread-0打印18
Thread-0打印19
Thread-0打印20
Thread-0打印21
Thread-0打印22
Thread-0打印23
Thread-0打印24
Thread-0打印25
Thread-0打印26
Thread-0打印27
Thread-0打印28
Thread-0打印29
Thread-0打印30
Thread-0打印31
Thread-0打印32
Thread-0打印33
Thread-1打印0
Thread-1打印1
Thread-1打印2
Thread-1打印3
Thread-1打印4
Thread-1打印5
Thread-1打印6
Thread-1打印7
Thread-1打印8
Thread-1打印9
Thread-1打印10
Thread-1打印11
Thread-1打印12
Thread-1打印13
Thread-1打印14
Thread-1打印15
Thread-1打印16
Thread-1打印17
Thread-1打印18
Thread-1打印19
Thread-1打印20
Thread-1打印21
Thread-1打印22
Thread-1打印23
Thread-1打印24
Thread-1打印25
Thread-1打印26
Thread-1打印27
Thread-1打印28
Thread-1打印29
Thread-1打印30
Thread-1打印31
Thread-1打印32
Thread-1打印33
Thread-1打印34
Thread-1打印35
Thread-1打印36
Thread-1打印37
Thread-1打印38
Thread-1打印39
Thread-0打印34
Thread-0打印35
Thread-0打印36
Thread-0打印37
Thread-0打印38
Thread-0打印39
第二个子线程返回的结果为:40
总结
1、Thread类的run()方法是一个空方法体,需要在子类中重写run()方法实现处理逻辑
2、直接调用线程对象的run()方法,jvm虚拟机不会将其识别为一个新的线程来运行,jvm虚拟机会将其识别成一个普通的方法来调用
3、线程的启动是start()而不是run()
4、在子类线程内部可通过Thread.currentThread().getName()来获取线程名
5、可以在测试的时候通过线程对象的getName()方法获取线程名
6、在同一个进程中,不同线程随机执行,即线程的执行具有随机性(比如上面的三个创建线程的方法测试的不管是for循环还是while循环,循环范围都弄得比较大,就是为了直观体现这一点,这个随机性在线程的学习中一直伴随我们,所以输出篇幅比较大也是这个原因,让大家比较直观的观察出来)
本文地址:https://blog.csdn.net/weixin_45851945/article/details/113994960