多线程基础篇(一)

操作系统中线程和进程的概念

进程是什么呢?
进程就是一个内存中运行的应用程序,每个进程都拥有自己的一个内存空间,一个进程中可以有多个线程,比如你在winds的任务管理器里面看到的就是一个个进程。
什么是线程呢?
线程是进程里面的一个执行流程,一个进程可以运行多个线程,因为一个进程中可以包含多个线程,比如java.exe进程中可以运行很多线程,比如tomcat,jdk等等,都在说多线程并发很高大上,其实严格意义上来讲多个线程并不是并发执行,是有先后顺序和优先级的,其中多线程的优先级可以由自己设定,只是运行轮换的速度太快,给你一种同时执行的错觉而已。举个一个进程包含多个进程的例子吧,你们都用过迅雷下载这个东西吧,当你同时下载好多资料的时候是不是看到好多东西在同时下载,实际上迅雷下载就是一个进程,其中一个个的下载的文件就是线程,是不是很形象
## Java中线程 ##
在java里面,每一个线程都有一个调用栈(后面会跟大家普及栈的概念),即使不在程序中创建任何新的线程,线程也在后台运行着。比如你平时写的一个普通的类,它中间也有线程的知识,public static void main(String args[]){},大家看到这个是不是很熟悉,基本上接触过你java语言的人都知道这是一个类的主函数,但是跟线程有什么关系呢,其实每个类的主函数就是一个主线程,每一个java应用都是从main函数开始运行的,而main方法是运行在一个线程内,因此main函数还有一个称呼就是主线程。
## java线程的三种创建方式 ##
是不是好多人以为java多线程实现只有两种方式,其实有三种实现方式,接下来我要总结下三种方式分别是怎么实现的
第一种方式:继承Thread类

public class TestThread extends Thread{
    public void run(){
        ......
    }
}

第二种实现多线程方式是实现Runnable接口

public class TestRunnable implements Runnable{
    @override
    public void run(){
        ......
    }
}

第三种方式是使用ExecutorService、Callable、Future实现有返回结果的多线程
ExecutorService、Callable、Future这个对象实际上都是属于Executor框架中的功能类。想要详细了解Executor框架的可以访问http://www.javaeye.com/topic/366591 ,这里面对该框架做了很详细的解释。返回结果的线程是在JDK1.5中引入的新特征,确实很实用,有了这种特征我就不需要再为了得到返回值而大费周折了,而且即便实现了也可能漏洞百出。
可返回值的任务必须实现Callable接口,类似的,无返回值的任务必须Runnable接口。执行Callable任务后,可以获取一个Future的对象,在该对象上调用get就可以获取到Callable任务返回的Object了,再结合线程池接口ExecutorService就可以实现传说中有返回结果的多线程了。下面提供了一个完整的有返回结果的多线程测试例子,在JDK1.5下验证过没问题可以直接使用。代码如下:

public class TestExecutorService {
    public static void main(String[] args) throws InterruptedException,
            ExecutionException {
        System.out.println("----程序开始运行----");
        Date date = new Date();
        int taskSize = 5;
        // 创建一个线程池
        ExecutorService pool = Executors.newFixedThreadPool(taskSize);
        // 创建有多个返回值的任务
        List<Future> list = new ArrayList<Future>();
        for (int i = 0; i < taskSize; i++) {
            Callable callable = new MyCallable(i + " ");
            // 执行任务并获取Future对象
            Future future = pool.submit(callable);
            list.add(future);
        }
        // 关闭线程池
        pool.shutdown();
        // 获取所有并发任务的运行结果
        for (Future future : list) {
            // 从Future对象上获取任务的返回值,并输出到控制台
            System.out.println(">>>" + future.get().toString());
        }
        Date date1 = new Date();
        System.out.println("----程序结束运行----,程序运行时间【"
                + (date1.getTime() - date.getTime()) + "毫秒】");

    }
}

class MyCallable implements Callable<Object> {
    private String taskNum;

    MyCallable(String taskNum) {
        this.taskNum = taskNum;
    }

    public Object call() throws Exception {
        System.out.println(">>>" + taskNum + "任务启动");
        Date dateTmp1 = new Date();
        Thread.sleep(1000);
        Date dateTmp2 = new Date();
        long time = dateTmp2.getTime() - dateTmp1.getTime();
        System.out.println(">>>" + taskNum + "任务终止");
        return taskNum + "任务返回运行结果,当前任务时间【" + time + "毫秒】";
    }
}

注:只是很简单的一个小例子,如果想要深入了解还需要看Callable和Future接口的API。

明后天的内容

明天后天总结下线程栈模型和线程变量的一些内容。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值