编程语言
首页 > 编程语言> > JAVA面向对象学习——java多线程———线程的创建和启动——使用Callable和Future创建线程

JAVA面向对象学习——java多线程———线程的创建和启动——使用Callable和Future创建线程

作者:互联网

Callable接口

 

 

Callable接口,该接口怎么看都像是Runnable接口的增强版,Callable接口也提供了一个call()方法可以作为线程执行体,但call方法比run()方法功能更强大:

 

——call()方法可以有返回值。

 

——call()可以声明抛出异常。

 

 

 

Future接口

 

 

JDK1.5提供了Future接口来代表Callable接口里call()方法的返回值,并为Future接口提供了一个FutureTask实现类,该实现类实现了Future接口,并实现了Runnable接口——可以作为Thread类的target。

 

 

 

 

 

实现Callable创建多线程

 

 

 

(1)定义Callable接口的实现类,并重写该接口的call方法,该call方法的方法体同样是该线程的线程执行体。

 

(2)创建Callable实现类的实例,并将该实例包装成FutureTask,FutureTask实现了Runnable接口。

 

(3)将FutureTask实例作为Thread的target来创建Thread对象,该Thread对象才是真正的线程对象。

 

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

 

 

 

 

 

 

 

 

 

 

 

 

 

 

import java.util.concurrent.*;


public class ThirdThread
{
	public static void main(String[] args)
	{
		// 创建Callable对象
		var rt = new ThirdThread();
		// 先使用Lambda表达式创建Callable<Integer>对象
		// 使用FutureTask来包装Callable对象
		FutureTask<Integer> task = new FutureTask<>((Callable<Integer>)() -> {
			var i = 0;
			for ( ; i < 100; i++)
			{
				System.out.println(Thread.currentThread().getName()
					+ " 的循环变量i的值:" + i);
			}
			// call()方法可以有返回值
			return i;
		});
		for (var i = 0; i < 100; i++)
		{
			System.out.println(Thread.currentThread().getName()
				+ " 的循环变量i的值:" + i);
			if (i == 20)
			{
				// 实质还是以Callable对象来创建、并启动线程
				new Thread(task, "有返回值的线程").start();
			}
		}
		try
		{
			// 获取线程返回值
			System.out.println("子线程的返回值:" + task.get());
		}
		catch (Exception ex)
		{
			ex.printStackTrace();
		}
	}
}

  

 

 

 

===================================================

 

 

 

 

 

import java.util.concurrent.*;

public class ThirdThread
{
    public static void main(String[] args)
    {
        ThirdThread rt = new ThirdThread();

        FutureTask<Integer> task = new FutureTask<>((Callable<Integer>)() -> {
            int i = 0;
            for ( ; i < 100; i++)
            {
                System.out.println(Thread.currentThread().getName() + "-------------" + i);
            }
            return i;
        });

        for (int i = 0; i < 100; i++)
        {
            System.out.println(Thread.currentThread().getName() + "+++++++++++++++" + i);
            if (i == 20)
            {
                new Thread(task, "return  ").start();
            }
        }
        try
        {
            System.out.println("子线程的返回值:" + task.get());
        }
        catch (Exception ex)
        {
            ex.printStackTrace();
        }
    }
}

  

 

 

 

下午 03:01:45: Executing task 'ThirdThread.main()'...

> Task :compileJava
> Task :processResources NO-SOURCE
> Task :classes

> Task :ThirdThread.main()

 


main+++++++++++++++0
main+++++++++++++++1
main+++++++++++++++2
main+++++++++++++++3
main+++++++++++++++4
main+++++++++++++++5
main+++++++++++++++6
main+++++++++++++++7
main+++++++++++++++8
main+++++++++++++++9
main+++++++++++++++10
main+++++++++++++++11
main+++++++++++++++12
main+++++++++++++++13
main+++++++++++++++14
main+++++++++++++++15
main+++++++++++++++16
main+++++++++++++++17
main+++++++++++++++18
main+++++++++++++++19
main+++++++++++++++20
main+++++++++++++++21
main+++++++++++++++22
main+++++++++++++++23
main+++++++++++++++24
main+++++++++++++++25
main+++++++++++++++26
main+++++++++++++++27
main+++++++++++++++28
main+++++++++++++++29
main+++++++++++++++30
main+++++++++++++++31
main+++++++++++++++32
main+++++++++++++++33
main+++++++++++++++34
main+++++++++++++++35
main+++++++++++++++36
main+++++++++++++++37
main+++++++++++++++38
main+++++++++++++++39
return -------------0
main+++++++++++++++40
return -------------1
return -------------2
return -------------3
return -------------4
return -------------5
return -------------6
main+++++++++++++++41
return -------------7
return -------------8
return -------------9
return -------------10
return -------------11
return -------------12
main+++++++++++++++42
main+++++++++++++++43
main+++++++++++++++44
main+++++++++++++++45
main+++++++++++++++46
main+++++++++++++++47
main+++++++++++++++48
main+++++++++++++++49
main+++++++++++++++50
main+++++++++++++++51
main+++++++++++++++52
main+++++++++++++++53
main+++++++++++++++54
main+++++++++++++++55
main+++++++++++++++56
main+++++++++++++++57
main+++++++++++++++58
main+++++++++++++++59
main+++++++++++++++60
main+++++++++++++++61
main+++++++++++++++62
main+++++++++++++++63
main+++++++++++++++64
main+++++++++++++++65
main+++++++++++++++66
main+++++++++++++++67
return -------------13
return -------------14
return -------------15
main+++++++++++++++68
return -------------16
main+++++++++++++++69
main+++++++++++++++70
main+++++++++++++++71
main+++++++++++++++72
main+++++++++++++++73
main+++++++++++++++74
main+++++++++++++++75
main+++++++++++++++76
main+++++++++++++++77
main+++++++++++++++78
return -------------17
main+++++++++++++++79
main+++++++++++++++80
main+++++++++++++++81
main+++++++++++++++82
main+++++++++++++++83
main+++++++++++++++84
main+++++++++++++++85
main+++++++++++++++86
main+++++++++++++++87
main+++++++++++++++88
main+++++++++++++++89
return -------------18
main+++++++++++++++90
main+++++++++++++++91
main+++++++++++++++92
main+++++++++++++++93
main+++++++++++++++94
main+++++++++++++++95
main+++++++++++++++96
main+++++++++++++++97
main+++++++++++++++98
main+++++++++++++++99
return -------------19
return -------------20
return -------------21
return -------------22
return -------------23
return -------------24
return -------------25
return -------------26
return -------------27
return -------------28
return -------------29
return -------------30
return -------------31
return -------------32
return -------------33
return -------------34
return -------------35
return -------------36
return -------------37
return -------------38
return -------------39
return -------------40
return -------------41
return -------------42
return -------------43
return -------------44
return -------------45
return -------------46
return -------------47
return -------------48
return -------------49
return -------------50
return -------------51
return -------------52
return -------------53
return -------------54
return -------------55
return -------------56
return -------------57
return -------------58
return -------------59
return -------------60
return -------------61
return -------------62
return -------------63
return -------------64
return -------------65
return -------------66
return -------------67
return -------------68
return -------------69
return -------------70
return -------------71
return -------------72
return -------------73
return -------------74
return -------------75
return -------------76
return -------------77
return -------------78
return -------------79
return -------------80
return -------------81
return -------------82
return -------------83
return -------------84
return -------------85
return -------------86
return -------------87
return -------------88
return -------------89
return -------------90
return -------------91
return -------------92
return -------------93
return -------------94
return -------------95
return -------------96
return -------------97
return -------------98
return -------------99
子线程的返回值:100

 

 

BUILD SUCCESSFUL in 2s
2 actionable tasks: 2 executed
下午 03:01:48: Task execution finished 'ThirdThread.main()'.

 

 

===========================================================

 

 

 

 

两种线程方式的对比

 

 

采用实现Runnable接口方式的多线程:

 

 

——线程类只是实现了Runnable接口,还可以可以继承其他类。

 

——在这种方式下,可以多个线程共享同一个target对象,所以非常适合多个相同线程来处理同一份资源的情况,从而可以将CPU,代码和数据分开,

        形成清晰的模型,较好地体现了面向对象的思想。

 

——劣势是:编程稍稍复杂,如果需要访问当前线程,必须使用Thread.currentThread()方法。

 

 

 

 

 

 

采用继承Thread类方式的多线程:

 

劣势是:因为线程类已经继承了Thread类,所以不能再继承其他父类。

 

优势是:编写简单,如果需要访问当前线程,无需使用Thread.currentThread()方法,直接使用this即可获得当前线程。

标签:Thread,+++++++++++++++,创建,接口,Callable,线程,-------------,多线程
来源: https://www.cnblogs.com/xiaobaibailongma/p/16062968.html