关闭

Java 并发编程深入学习(一)——实现多线程的方式

标签: java多线程编程并发线程
662人阅读 评论(0) 收藏 举报
分类:

介绍

Java 并发编程的好处在于以下几点:

1.资源利用率更好
2. 简化程序设计
3. 程序响应更快

实现方式

继承Thread类

class MyThread extends Thread{  
    private int ticket = 5;  
    public void run(){  
        for (int i=0;i<10;i++)  
        {  
            if(ticket > 0){  
                System.out.println("ticket = " + ticket--);  
            }  
        }  
    }  
}  

public class ThreadDemo{  
    public static void main(String[] args){  
        new MyThread().start();  
        new MyThread().start();  
        new MyThread().start();  
    }  
} 

实现Runnable接口

Java 5以前实现多线程有两种实现方法:一种是继承Thread类;另一种是实现Runnable接口。两种方式都要通过重写run()方法来定义线程的行为,推荐使用后者,因为Java中的继承是单继承,一个类有一个父类,如果继承了Thread类就无法再继承其他类了,显然使用Runnable接口更为灵活。

实现Runnable接口相比继承Thread类有如下优势:

可以避免由于Java的单继承特性而带来的局限
增强程序的健壮性,代码能够被多个程序共享,代码与数据是独立的
适合多个相同程序代码的线程区处理同一资源的情况

实现Callable接口

Java 5以后创建线程还有第三种方式:实现Callable接口,该接口中的call方法可以在线程执行结束时产生一个返回值。

使用Callable+Future获取执行结果

public class CallableDemo implements Callable<Integer> {  

    private int sum;  
    @Override  
    public Integer call() throws Exception {  
        System.out.println("Callable子线程开始计算啦!");  
        Thread.sleep(2000);  

        for(int i=0 ;i<5000;i++){  
            sum=sum+i;  
        }  
        System.out.println("Callable子线程计算结束!");  
        return sum;  
    }  
}  

Callable执行测试类如下:


public class CallableTest {  

    public static void main(String[] args) {  
        //创建线程池  
        ExecutorService es = Executors.newSingleThreadExecutor();  
        //创建Callable对象任务  
        CallableDemo calTask=new CallableDemo();  
        //提交任务并获取执行结果  
        Future<Integer> future =es.submit(calTask);  
        //关闭线程池  
        es.shutdown();  
        try {  
            Thread.sleep(2000);  
        System.out.println("主线程在执行其他任务");  

        if(future.get()!=null){  
            //输出获取到的结果  
            System.out.println("future.get()-->"+future.get());  
        }else{  
            //输出获取到的结果  
            System.out.println("future.get()未获取到结果");  
        }  

        } catch (Exception e) {  
            e.printStackTrace();  
        }  
        System.out.println("主线程在执行完成");  
    }  
}  

执行结果:

Callable子线程开始计算啦!
主线程在执行其他任务
Callable子线程计算结束!
future.get()-->12497500
主线程在执行完成

使用Callable+FutureTask获取执行结果

public class CallableTest {  

    public static void main(String[] args) {  
//      //创建线程池  
//      ExecutorService es = Executors.newSingleThreadExecutor();  
//      //创建Callable对象任务  
//      CallableDemo calTask=new CallableDemo();  
//      //提交任务并获取执行结果  
//      Future<Integer> future =es.submit(calTask);  
//      //关闭线程池  
//      es.shutdown();  

        //创建线程池  
        ExecutorService es = Executors.newSingleThreadExecutor();  
        //创建Callable对象任务  
        CallableDemo calTask=new CallableDemo();  
        //创建FutureTask  
        FutureTask<Integer> futureTask=new FutureTask<>(calTask);  
        //执行任务  
        es.submit(futureTask);  
        //关闭线程池  
        es.shutdown();  
        try {  
            Thread.sleep(2000);  
        System.out.println("主线程在执行其他任务");  

        if(futureTask.get()!=null){  
            //输出获取到的结果  
            System.out.println("futureTask.get()-->"+futureTask.get());  
        }else{  
            //输出获取到的结果  
            System.out.println("futureTask.get()未获取到结果");  
        }  

        } catch (Exception e) {  
            e.printStackTrace();  
        }  
        System.out.println("主线程在执行完成");  
    }  
}  

执行结果:

Callable子线程开始计算啦!
主线程在执行其他任务
Callable子线程计算结束!
futureTask.get()-->12497500
主线程在执行完成
0
0
查看评论

Java并发编程与技术内幕:线程池深入理解

首先,讲讲什么是线程池?照笔者的简单理解,其实就是一组线程实时处理休眠状态,等待唤醒执行。那么为什么要有线程池这个东西呢?可以从以下几个方面来考虑:其一、减少在创建和销毁线程上所花的时间以及系统资源的开销 。其二、2将当前任务与主线程隔离,能实现和主线程的异步执行,特别是很多可以分开重复执行的任务。...
  • Evankaka
  • Evankaka
  • 2016-06-08 08:38
  • 17272

C++11 并发编程教程&学习笔记

C++11 并发编程教程&学习笔记 参考: 1、原文:http://baptiste-wicht.com/posts/2012/03/cpp11-concurrency-part1-start-threads.html 2、译文:http://billhoo.blog...
  • huhaijing
  • huhaijing
  • 2016-06-24 19:07
  • 997

Java并发编程学习路线图

思维导图如下:
  • csujiangyu
  • csujiangyu
  • 2016-05-18 10:08
  • 838

多线程——Java多线程实现的三种方式

实现多线程的几种方式,建议使用runable实现,不管如何最终都需要thread.start( )来启动线程。
  • xdd19910505
  • xdd19910505
  • 2016-03-22 20:30
  • 2217

Java多线程实现的四种方式

Java多线程实现的方式有四种 1.继承Thread类,重写run方法 2.实现Runnable接口,重写run方法,实现Runnable接口的实现类的实例对象作为Thread构造函数的target 3.通过Callable和FutureTask创建线程 4.通过线程池创建线程前面两种可以归结为一类...
  • u011480603
  • u011480603
  • 2017-07-19 01:45
  • 1594

Java多线程的四种实现方式

 Java多线程实现方式主要有四种:继承Thread类、实现Runnable接口、实现Callable接口通过FutureTask包装器来创建Thread线程、使用ExecutorService、Callable、Future实现有返回结果的多线程。 其中前两种方式线程执行完后都...
  • a724888
  • a724888
  • 2017-04-10 21:53
  • 1008

《Java并发编程的艺术》读书笔记——Java内存模型

第三章 Java内存模型3.1 内存模型基础3.1.1 并发编程的两个关键问题 线程之间如何通信 java采用共享内存模型隐式通信 线程之间如何同步 共享内存模型模型需要显式指定同步 3.1.2 内存模型抽象结构3.1.3 从源代码到指令序列的重排序3.1.5 happens-beforeJSR...
  • shuxiangxingkong
  • shuxiangxingkong
  • 2016-09-13 10:49
  • 398

《深入理解计算机系统》--并发编程

这也是一本很出名的书,在很早的时候读过一些,这次从后面开始读,看有没有新的体会。     如果逻辑流在时间上重叠,那么他们就是并发的,硬件异常处理程序、进程和UNIX信号处理程序都是熟悉的例子。并发现象不仅在内核中存在,在应用级别的程序中也存在。 访问慢速的I/O...
  • yusiguyuan
  • yusiguyuan
  • 2013-10-13 14:09
  • 2124

JAVA多线程实现的三种方式

JAVA多线程实现方式主要有三种:继承Thread类、实现Runnable接口、使用ExecutorService、Callable、Future实现有返回结果的多线程。其中前两种方式线程执行完后都没有返回值,只有最后一种是带返回值的。 1、继承Thread类实现多线程 继承Thread类的方法...
  • aboy123
  • aboy123
  • 2014-07-31 18:34
  • 451863

对线程的深入学习(一)

1. 创建线程 int pthread_create (pthread_t* restrict thread, const pthread_attr_t* restrict attr, void* (*start_rou...
  • meetings
  • meetings
  • 2015-07-30 18:39
  • 684
    个人资料
    • 访问:130383次
    • 积分:3252
    • 等级:
    • 排名:第12388名
    • 原创:233篇
    • 转载:11篇
    • 译文:0篇
    • 评论:30条
    微信号

    微信号:code_horse 扫一扫添加关注

    Github
    博客专栏
    文章分类
    最新评论