旗下导航:搜·么
当前位置:网站首页 > JAVA教程 > 正文

java中完成多线程的几种体式格局【JAVA教程】,java,多线程,方式

作者:搜教程发布时间:2019-12-05分类:JAVA教程浏览:102评论:0


导读:Java多线程的运用有三种要领:继续Thread类、完成Runnable接口和运用Callable和Future建立线程。一、继续Thread类完成体式格局很简单,只须...

Java多线程的运用有三种要领:继续Thread类、完成Runnable接口和运用Callable和Future建立线程。

一、继续Thread类

完成体式格局很简单,只须要建立一个类去继续Thread类然后重写run要领,在main要领中挪用该类实例对象的start要领即可完成多线程并发。代码:

public class MyThread extends Thread {
    @Override
    public void run(){        
        super.run();
        System.out.println("实行子线程...");
    }
}

测试用例:

public class Test {
    public static void main(String[] args) {
        MyThread myThread = new MyThread();
        myThread.start();
        System.out.println("主线程...");
    }
}

运转效果:

固然,这里的效果不代表线程的实行递次,线程是并发实行的,假如多运转频频,打印递次大概会不一样。多线程的运转历程当中,CPU是以不确定的体式格局去实行线程的,故运转效果与代码的实行递次或许挪用递次无关,运转效果也大概不一样。

免费视频教程引荐:java进修视频

这里另有一个须要注重的点就是main要领中应当挪用的是myThread的start要领,而不是run()要领。挪用start()要领是通知CPU此线程已预备就绪能够实行,进而体系有时间就会来实行其run()要领。

而直接挪用run()要领,则不是异步实行,而是等同于挪用函数般按递次同步实行,这就失去了多线程的意义了。

二、完成Runnable接口

这类体式格局的完成也很简单,就是把继续Thread类改成完成Runnable接口。代码以下:

public class MyRunnable implements Runnable {    
    @Override
    public void run() {
        System.out.println("实行子线程...");
    }
}

测试用例:

public class Test {    
    public static void main(String[] args) {
        Runnable runnable = new MyRunnable();
        Thread thread = new Thread(runnable);
        thread.start();
        System.out.println("主线程运转完毕!");
    }
}

运转效果:

运转效果没啥好说的,这里main中能够看到真正建立新线程照样经由历程Thread建立:

Thread thread = new Thread(runnable);

这一步Thread类的作用就是把run()要领包装成线程实行体,然后依旧经由历程start去通知体系这个线程已预备好了能够部署实行。

三、运用Callable和Future建立线程

上面的两种体式格局都有这两个问题:

1、没法猎取子线程的返回值;

2、run要领不能够抛出非常。

为了处理这两个问题,我们就须要用到Callable这个接口了。说到接口,上面的Runnable接口完成类实例是作为Thread类的组织函数的参数传入的,以后经由历程Thread的start实行run要领中的内容。然则Callable并非Runnable的子接口,是个全新的接口,它的实例不能直接传入给Thread组织,所以须要另一个接口来转换一下。

Java5供应了Future接口来代表Callable接口里call()要领的返回值,并为Future接口供应了一个完成类FutureTask,该完成类的继续关联如图所示:

能够看到,该完成类不仅完成了Future接口,还完成了Runnable接口,所以能够直接传给Thread组织函数。

而关于FutureTask的组织函数以下:

所以这内里实在就是要比上一个要领再多一个转换历程,终究一样是经由历程Thread的start来建立新线程。有了这个思绪,代码就很轻易理解了:

import java.util.concurrent.Callable;
public class MyCallable implements Callable {    
int i = 0;    
@Override
    public Object call() throws Exception {
        System.out.println(Thread.currentThread().getName()+"  i的值:"+ i);        
        return i++; //call要领能够有返回值
    }
}

测试:

import java.util.concurrent.Callable;
import java.util.concurrent.FutureTask;
public class Test {
    public static void main(String[] args) {
        Callable callable = new MyCallable();        
        for (int i = 0; i < 10; i++) {
            FutureTask task = new FutureTask(callable);            
            new Thread(task,"子线程"+ i).start();            
            try {                //猎取子线程的返回值
                System.out.println("子线程返回值:"+task.get() + "\n");
            }  catch (Exception e) {
                e.printStackTrace();
            }
        }
    }
}

实行效果(部份):

相干文章教程引荐:java入门顺序

以上就是java中完成多线程的几种体式格局的细致内容,更多请关注ki4网别的相干文章!

标签:java多线程方式


欢迎 发表评论: