java多线程编程--如何开始一个线程

如何开始一个线程

1. java多线程的实现方式

1.1 继承Thread类

定义类如下:

public SubThread extends Thread {
     @override
     public void run() {
         ...
     }
}

使用时:

Thread subThread = new SubThread();
subThread.start();

可以使用Thread类已有的函数进行操作。

1.2 实现Runnable接口

定义类如下:

public SubThread implements Runnable {
    public void run() {
    // doSomething...
    }
}

使用时:

SubThread subThread = new SubThread();
Thread thread = new Thread(subThread);
thread.start();

使用该方式实现的类其实是一个普通类,只是它实现了线程的run方法,因而将其注册到Thread类的对象中才能作为一个线程运行。

1.3 实现Callable接口

类定义如下:

public SubThread implements Callable<String> {
    public String call() {
        // do something...
    }
}

可以看出,通过这种方式实现的线程带有返回值,Callable<String>指定返回值类型,并且Callable可以抛出异常,而Runnable则不能。

另外,查看Thread类会发现,Thread类并直接支持Callable,因而Callable要配合其他类才能好好工作。

支持Callable的途径有好几种,这里只写一种自己试验过的,其他的等以后再补充。

(1)配合FutureTask

FutureTask<V>实现了Runnable接口和Future接口(Futur可以获取异步线程执行的返回值),因此可以利用FutureTask来实现开始线程并获取线程执行结果。

示例如下:

public class TestCallable implements Callable<String> {
    public String call() throws InterruptedException {
        Thread.sleep(5000);
        return "call return";
    }

    public static void main(String[] args) {
        TestCallable test = new TestCallable();
        FutureTask<String> futrue = new FutureTask<String>(test);
        Thread thread = new Thread(futrue);
        thread.start();
        // 在需要结果之前,可以坐其他事
        System.out.println("hello");
        try {
            System.out.println(futrue.get());
        } catch (ExecutionException e) {
            System.out.println("执行callable时出错");
        } catch (InterruptedException e) {
            System.out.println("执行callable时出错");
        }
        System.out.println("结束语");
    }
}

输出结果:

hello
call return
结束语

可以看出,在要使用子线程的执行结果之前,我们可以坐一些其他事情,等需要用的时候,调用Future的get()方法就可以获取子线程的执行结果。

注意,Future的get()方法会一直阻塞到子线程执行结束。当然,我们可以使用get(long timeout, TimeUnit unit)函数来指定等待时间。

(2)TODO 配合ExecutorService 

通过ExecutorService的submit方法可以执行Callable,对于线程池这一块暂时还没多少了解,后续自己实践之后再补充^ ^。

2. 总结

起始研究Thread类就能发现,extends Thread 和 implements Runable是实现一个线程的最基本的方式,FutureTask这些都是在Runnable这块基石上实现的,Callable则必须依赖其他支持它的类才能执行,不然它和线程是没有半毛钱关系的。打好底层基础对于理解一些高层的用法非常有帮助,不然只是知其然不知其所以然。就像你如果不知道TCP协议,在用java网络编程时,对于出现的一些奇怪的现象,你就不知道是底层协议的原因,还是java自身的原因一样...扯远了~~

对于上述几种方式的选择,其实按需要来就行:

extends Thread的优点是你可以直接使用父类Thread给你提供的线程操作的方法,而缺点是java的类不支持多继承,因此使用起来可能没那么自由。

implements Runnable的优点是你可以实现其他多个接口,也可以继承其他类,自由度大大提高,而缺点则是对于线程的操作,要费一点心思^ ^。相对于继承Thread类,推荐使用实现Runnable的方式,这样程序扩展性更高。

implements Callable的优点是可以返回线程执行结果,抛出异常,对于要使用其他线程的执行结果的场景来说非常有用。

版权声明:本文为博主原创文章,未经博主允许不得转载。

时间: 2024-10-08 08:57:29

java多线程编程--如何开始一个线程的相关文章

java多线程编程--如何终止一个线程

1. Thread.stop()函数 stop()函数终止线程就像是强行拔掉电源线关机一样,可能会带来未知风险,因此目前不再推荐使用这种方式.请忘记它吧~~ 2. 改变标志变量状态 通常我们会在线程中使用一个标志变量来控制线程的运行,如: public class TestCallable implements Runnable { private boolean running = true; public void stop() { this.running = false; } publi

java多线程编程(1) 线程的基本知识

在前面研究过多线程与进程的区别. 这里在稍微总结一下: 进程:程序动态的一次执行过程. 线程:可以只是程序员的一部分的执行过程 每个进程有多个线程组成,在java程序中,至少两个线程一个是垃圾回收线程和main线程. 线程占有的资源更少,早java中就是每个线程都有自己的工作区,就是有自己独立的栈空间.多个线程共享一些内存资源,堆是共享的. 多线程的力度小,并发度高,这样系统的吞吐量就很大,只有好处吗?调度和执行线程是需要资源的,就是像是数据库中的索引和数据库中的锁一个道理,并发会带来什么问题呢

Java多线程编程7--拾遗增补--线程组

可以把线程归属到某一个线程组中,线程组中可以有线程对象,也可以有线程组,组中还可以有线程.这样的组织结构有些类似于树的形式,如图所示. 线程组的作用是,可以批量的管理线程或线程组对象,有效地对线程或线程组对象进行组织. 1.线程对象关联线程组:1级关联 所谓的1级关联就是父对象中有子对象,但并不创建子孙对象.这种情况经常出现在开发中,比如创建一些线程时,为了有效地对这些线程进行组织管理,通常的情况下是创建一个线程组,然后再将部分线程归属到该组中.这样的处理可以对零散的线程对象进行有效的组织与规划

Java多线程编程7--拾遗增补--线程的状态(new,runnable,terminated,timed_waiting,waiting,blocked)

线程对象在不同的运行时期有不同的状态,状态信息就存在于Thread内部类的State枚举类中 public enum State { /** * new状态是线程实例化后还从未执行start()方法时的状态 */ NEW, /** * runnable状态是线程进人运行的状态 */ RUNNABLE, /** * blocked状态出现在某一个线程在等待锁的时候. */ BLOCKED, /** * waiting是线程执行了Object.wait()方法后所处的状态 */ WAITING, /

Java多线程编程(三)线程的优先级、同步与死锁

线程的优先级: 线程的优先级分为三种,分别是: 1-MIN_PRIORITY 10-MAX_PRIORITY 5-NORM_PRIORITY 如果什么都不设置默认值是5 线程的优先级可以影响线程的执行顺序,当然这里指的是有可能影响,不会一定影响.在默认状态下(比如说主线程)它的默认值是5 具体代码演示: package com.yeqc.thread; class ThRun implements Runnable{ @Override public void run() { for(int i

Java多线程编程基础之线程对象

在进入java平台的线程对象之前,基于基础篇(一)的一些问题,我先插入两个基本概念. [线程的并发与并行] 在单CPU系统中,系统调度在某一时刻只能让一个线程运行,虽然这种调试机制有多种形式(大多数是时间片轮巡为主),但无论如何,要通过不断切换需要运行的线程让其运行的方式就叫并发(concurrent).而在多CPU系统中,可以让两个以上的线程同时运行,这种可以同时让两个以上线程同时运行的方式叫做并行(parallel). 在上面包括以后的所有论述中,请各位朋友谅解,我无法用最准确的词语来定义储

Java多线程编程模式实战指南(二):Immutable Object模式--转载

本文由本人首次发布在infoq中文站上:http://www.infoq.com/cn/articles/java-multithreaded-programming-mode-immutable-object.转载请注明作者: 黄文海 出处:http://viscent.iteye.com. 多线程共享变量的情况下,为了保证数据一致性,往往需要对这些变量的访问进行加锁.而锁本身又会带来一些问题和开销.Immutable Object模式使得我们可以在不使用锁的情况下,既保证共享变量访问的线程安

java多线程编程

一.多线程的优缺点 多线程的优点: 1)资源利用率更好2)程序设计在某些情况下更简单3)程序响应更快 多线程的代价: 1)设计更复杂虽然有一些多线程应用程序比单线程的应用程序要简单,但其他的一般都更复杂.在多线程访问共享数据的时候,这部分代码需要特别的注意.线程之间的交互往往非常复杂.不正确的线程同步产生的错误非常难以被发现,并且重现以修复. 2)上下文切换的开销当CPU从执行一个线程切换到执行另外一个线程的时候,它需要先存储当前线程的本地的数据,程序指针等,然后载入另一个线程的本地数据,程序指

Java并发编程:进程和线程

.title { text-align: center } .todo { font-family: monospace; color: red } .done { color: green } .tag { background-color: #eee; font-family: monospace; padding: 2px; font-size: 80%; font-weight: normal } .timestamp { color: #bebebe } .timestamp-kwd