Java实现多线程的三种方式

Java多线程

基本概念:

进程:程序的一次完整运行

同一个时间点上,会有多个进程轮流抢占资源,但在某个时间点上,只会有一个进程运行;

线程:是进程基础上进一步的划分结果,即:一个进程上可以同时创建多个线程;

线程的存在离不开进程;

java三种多线程实现方式(JDK1.5后增加了第三种):

1:继承Thread类;

2:实现Runnable接口;

3:实现Callable接口。

(1)继承Thread类:

所有程序都有起点main方法,线程同样也有起点,这个起点就是run方法, 在每个线程操作主类里都必须覆写Thread类中提供的run方法;

Public void run(){};

这个方法没有返回值,代表了线程一旦开始就无法结束不能返回内容;

一个简单多线程的例子:

class Mythread extends Thread {
	private String name ;
	public Mythread (String name) {
		this.name = name ;
	}
	public void run() {
		for(int i = 0; i < 200; i++) {
			System.out.println(this.name + "--->" + i);
		}
	}
}

public class 继承Thread类 {

	public static void main(String[] args) {
		// TODO Auto-generated method stub
		Mythread m1 = new Mythread("线程A") ;
		Mythread m2 = new Mythread("线程B") ;
		Mythread m3 = new Mythread("线程C") ;
		
		m1.start();
		m2.start();
		m3.start();
	}
}

为什么多线程启动不用run(),而用start()?

使用thread类的start()方法不仅要启动多线程,还要根据不同的操作系统进行资源的分配,而且start()方法也调用了run()方法。当执行了start()方法,线程处于就绪状态,执行run()时,线程属于运行状态,直接调用run()方法和执行普通方法没有区别。

  1. 实现Runnable接口:

因为java单继承的局限性,我们提供Runnable接口,此接口定义如下:

public interface Runnable{
	public void run() ;
}

这个run()方法也需要覆写;

任何时候启动多线程都需要用到Thread类里的start()方法,但实现Runnable接口没有srart()方法以供使用。

在Tread类里面定义有如下构造方法:

public Thread(Runnable target);(这代表了可以接受Runnable接口的对象)

class Mythread implements Runnable {
	private String name ;
	public Mythread (String name) {
		this.name = name ;
	}
	public void run() {
		for(int i = 0; i < 200; i++) {
			System.out.println(this.name + "--->" + i);
		}
	}
}
public class 实现Runnable接口 {

	public static void main(String[] args) {
		// TODO Auto-generated method stub
		Mythread m1 = new Mythread("线程A") ;
		Mythread m2 = new Mythread("线程B") ;
		Mythread m3 = new Mythread("线程C") ;
		
		new Thread(m1).start();
		new Thread(m2).start();
		new Thread(m3).start();	
}
}

多线程的两种实现方式的区别?(面试题)

1:Thread类是Runnable接口的子类(Thread实现了Runnable接口),使用Runnable可以解决单继承的的局限性;

2:Runnable接口实现的多线程可以比Thread类实现的更好的表达数据共享的概念。

(3)Callable接口

为了解决Runnable接口中run()方法没有返回结果的问题,提供了Callable接口。

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

class mythread implements Callable<String>{

	private int ticket = 10 ;
	@Override
	public String call() throws Exception {
		// TODO Auto-generated method stub
		for(int i = 0; i < 100; i++) {
			if(this.ticket > 0) {
				System.out.println("卖票:ticket = " + ticket--);
			}
		}
		return "票以卖光!";
	}
}
public class 实现Callable接口 {

	public static void main(String[] args) throws Exception {
		// TODO Auto-generated method stub
		mythread m1 = new mythread() ;
		mythread m2 = new mythread() ;
		
		FutureTask<String> task1 = new FutureTask<String>(m1) ;
		FutureTask<String> task2 = new FutureTask<String>(m2) ;
		/*FutureTask是Runnable接口的子类,所以可以使用Thread的构造方法接受它的对象*/
		new Thread(task1).start();
		new Thread(task2).start();
		/*多线程执行完后可以用FutureTask的父接口Future的get()方法取得返回结果*/
		System.out.println("1线程的返回结果:" + task1.get());
		System.out.println("2线程的返回结果:" + task2.get());
	}

}

这个是我在网易云课堂看视频跟老师一起总结的,有问题的可以互相讨论。

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值