【JAVA并发学习一】并发和多线程

来源:互联网 发布:mac散热差怎么办 编辑:程序博客网 时间:2024/05/21 16:57

一 什么是线程

现代操作系统在运行一个程序时,会为其创建一个进程。例如,启动一个Java程序,操作系统就会创建一个Java进程。线程概念是在进程基础上定义的,线程是现代操作系统能够调度的最小单元,它被包含在进程之中,是行程中的实际运作单位。 一条线程指的是进程中一个单一顺序的控制流,一個进程中可以並行多個线程,每条线程并行执行不同的任务。

一个Java程序从main( )方法开始执行,然后根据既定的代码逻辑执行,看似没有其他线程的参与,但实际上java程序天生就是多线程程序,因为执行main( )方法就是一个名称为mian( )进程。一个最普通java程序,至少具备以下几个线程:

public class Main {        public static void main(String[] args) {            ThreadGroup group = Thread.currentThread().getThreadGroup();            ThreadGroup topGroup = group;            // 遍历线程组树,获取根线程组            while (group != null) {                topGroup = group;                group = group.getParent();            }            // 激活的线程数再加一倍,防止枚举时有可能刚好有动态线程生成            int slackSize = topGroup.activeCount() * 2;            Thread[] slackThreads = new Thread[slackSize];            // 获取根线程组下的所有线程,返回的actualSize便是最终的线程数            int actualSize = topGroup.enumerate(slackThreads);            Thread[] atualThreads = new Thread[actualSize];            // 复制slackThreads中有效的值到atualThreads            System.arraycopy(slackThreads, 0, atualThreads, 0, actualSize);            System.out.println("Threads size is " + atualThreads.length);            for (Thread thread : atualThreads) {                System.out.println(thread.getName());            }        }    }

打印结果:

    Threads size is 5    Reference Handler   //清除Reference的线程    Finalizer           //调用对象difalize方法的接口    Signal Dispatcher   //分发处理发给JVM信号的线程    main                //main线程,用户程序入口

二 为什么使用多线程

使用多线程的理由之一是和进程相比,它是一种常花销小,切换快,更”节俭”的多任务操作方式。在Linux系统下,启动一个新的进程必须分配给它独立的地址空间,建立众多的数据表来维护它的代码段、堆栈段和数据段,这是一种”昂贵”的多任务工作方式。而运行于一个进程中的多个线程,它们彼此之间使用相同的地址空间,共享大部分数据,启动一个线程所花费的空间远远小于启动一个进程所花费的空间,而且,线程间彼此切换所需的时间也远远小于进程间切换所需要的时间。

使用多线程的理由之二是线程间方便的通信机制。对不同进程来说,它们具有独立的数据空间,要进行数据的传递只能通过通信的方式进行,这种方式不仅费时,而且很不方便。线程则不然,由于同一进程下的线程之间共享数据空间,所以一个线程的数据可以直接为其它线程所用,这不仅快捷,而且方便。当然,数据的共享也带来其他一些问题,有的变量不能同时被两个线程所修改,有的子程序中声明为static的数据更有可能给多线程程序带来灾难性的打击,这些正是编写多线程程序时最需要注意的地方。

原创粉丝点击