多线程的创建

时间:2021-2-26 作者:admin

文章目录


前言

记得好几年前无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循环,循环范围都弄得比较大,就是为了直观体现这一点,这个随机性在线程的学习中一直伴随我们,所以输出篇幅比较大也是这个原因,让大家比较直观的观察出来)

声明:本文内容由互联网用户自发贡献自行上传,本网站不拥有所有权,未作人工编辑处理,也不承担相关法律责任。如果您发现有涉嫌版权的内容,欢迎进行举报,并提供相关证据,工作人员会在5个工作日内联系你,一经查实,本站将立刻删除涉嫌侵权内容。