栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > Java

多线程的创建java

Java 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

多线程的创建java

方法1:继承Thread类

1定义一个子类继承线程类java.long.Thread ,重写run()方法

2创建一个子类对象

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

第一种方法

public class MyThread extends Thread {
	@Override
	//run方法里面写要执行的东西
	public void run() {
		// TODO Auto-generated method stub
		super.run();
		for(int i=0;i<5;i++) {
			System.out.println("子线程"+i);
		}
	
	}

}
第一种方法
public class Test1 {

	public static void main(String[] args) {
		// TODO Auto-generated method stub
		Thread t=new MyThread();//创建线程对象
		t.start();//调用线程的启动方法
		for(int i=0;i<5;i++) {
			System.out.println("主线程"+i);
		}
		

	}

}

方式1的优缺点?

优点编码简单

缺点:存在单继承的局限性,线程类已经继承了Thread,无法继承其他类,不利于扩展

为什么不直接调用run方法,而是调用strat启动线程?

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

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

为什么不能把主线程任务放在子线程之前?

这样主线程一直就是先跑完的,相当于一个单线程的效果了

多线程的创建方式二(实现Runnable接口)

1定义一个线程任务类MyRunnable实现Runnable接口,重新run方法

2创建一个MyRunnable任务对象

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

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

Thread构造器

public Thread(String name) 可以为当前线程指定名称

public Thread (Runnable target)  封装Runnable对象成线程对象

Public Thread (Runnable target, String name )封装Runnable 对象成线程对象并指定线程名称

//第二种方法

public class MyRunnable  implements Runnable{
	@Override
	//写线程任务
	public void run() {
		// TODO Auto-generated method stub
		for(int i=0;i<5;i++) {
			System.out.println("子线程被执行"+i);
		}
	}

}

package 多线程;

public class Test2 {
//第二种方法

	public static void main(String[] args) {
		// TODO Auto-generated method stub
		Runnable r=new MyRunnable(); //创建任务对象
		Thread t=new Thread(r);//封装成线程对象
		t.start(); //启动线程
		for(int i=0;i<5;i++) {
			System.out.println( "主线程被执行"+i);
		}
		

	}

}

方式二优缺点

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

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

线程创建方式2(匿名内部类写法)
//第二种方式的匿名内部类写法

public class Test5 {

	public static void main(String[] args) {
		Thread t=new Thread(new Runnable() {
			
			@Override
			public void run() {
				for(int i=0;i<5;i++) {
					System.out.println("子线程"+i);
				}
				
			}
		});
		t.start();
		for(int i=0;i<5;i++) {
			System.out.println("主线程被执行"+i);
		}
	}

}

可以用Lamubda表达式继续简化为

		Thread t=new Thread(()-> {
				for(int i=0;i<5;i++) {
					System.out.println("子线程"+i);
				}		
		});

前两种创建方式都存在一个问题?

他们重写的run方法均不能直接返回结果

不适合需要返回线程执行结果的业务场景

怎么解决这个问题呢?

JDK5.0提供了Callable和FutureTask来实现

第三种方式:利用Callable、FutureTask接口实现

1得到任务对象 定义类实现Callable接口,重写call方法,封装要做的事情;用FutureTask把Callable对象封装成线程对象

2把线程对象交给Thread处理

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

4线程执行完毕,通过FutureTask的get方法获取任务执行的结果

//第三种方式

import java.util.concurrent.Callable;

public class Threesum  implements Callable{
	private int a;
	private int b;
	
	public Threesum(int a, int b) {
		super();
		this.a = a;
		this.b = b;
	}

	//写要执行的任务
	//我的功能是求和
	@Override
	public Integer call() throws Exception {
		// TODO Auto-generated method stub
		int sum=a+b;
		return sum;
	}

}

主函数

//第三种方式

import java.util.concurrent.Callable;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.FutureTask;

public class Test6 {

	public static void main(String[] args) {
		// 创建Callable对象
		Callable ca=new Threesum(10,20); 
		//把Callable 对象包装为 FutureTask对象
		FutureTask fu=new FutureTask<>(ca);
		//FutureTask交给线程对象Thread
		Thread s=new Thread(fu);
		//开始执行
		s.start(); 
		//看结果用FutureTask的get方法
		try {
			int sum=fu.get();
			System.out.println("第三种方法写的线程输出结果为:"+sum);
		} catch (InterruptedException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (ExecutionException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		
		

	}

}

方式三优缺点

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

可以在线程执行完毕后去获取线程执行的结果

缺点:代码复杂一点

转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/1021201.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号