多线程JAVA篇(一)

解析AsyncTask源码之前,首先讲述与之相关的Java线程知识:

知识点清单
1、Thread类
2、Runnable接口
3、Callable接口
4、synchronized关键字
5、volatile关键字
6、Future接口
7、RunnableFuture接口
8、FutureTask类
9、线程池的相关知识

/**
     * A representation of a thread‘s state. A given thread may only be in one
     * state at a time.
     */
    public enum State {
        /**
         * The thread has been created, but has never been started.
         */
        NEW,
        /**
         * The thread may be run.
         */
        RUNNABLE,
        /**
         * The thread is blocked and waiting for a lock.
         */
        BLOCKED,
        /**
         * The thread is waiting.
         */
        WAITING,
        /**
         * The thread is waiting for a specified amount of time.
         */
        TIMED_WAITING,
        /**
         * The thread has been terminated.
         */
        TERMINATED
    }

大家发现这个枚举里面列举了六种状态,实际上线程一共只有四种状态:
1、新建(NEW):当线程被创建时,它只会短暂处于这种状态。此时它已经分配了必需的系统资源,并执行了初始化。此刻线程已经有了资格获得CPY时间,之后调度器将把这个线程转变为可运行状态或阻塞状态。
2、就绪(RUNNABLE):在这种状态下,只要调度器把时间片分配给线程,线程就可以运行。也就是说,在任意时刻,线程可以运行也可以不运行。只要调度器能分配时间片给线程,它就可以运行;这不同于死亡和阻塞状态。
3、阻塞(BLOCKED、WAITING、TIMED_WAITING):线程能够运行,但有某个条件阻止它的运行。当线程处于阻塞状态时,调度 器将会忽略线程,不会分配给线程任何CPU时间。直到线程重新进入就绪状态,它才有可能执行操作
4、死亡(TERMINATED)处于死亡或终止状态的线程将不再是可调度的,并且再也不会得到CPU时间,它的任务已结束,或不再是可运行的。任务死亡的通常方式从run方法返回,但是任务的线程还可以被中断,你将要看到这一点。
下面通过代码实例的方法为大家演示这六种状态:

public class ThreadTest {

    public static void main(String[] args) {
        final Thread thread = new Thread(new Runnable() {

            @Override
            public void run() {
                for (int i = 0; i < 10000; i++) {

                }

            }
        });

        System.out.println("线程名" + thread.getName() + "线程状态" +thread.getState());

        thread.start();

        System.out.println("线程名" + thread.getName() + "线程状态" +thread.getState());

        Thread threadTest = new Thread(new Runnable() {

            @Override
            public void run() {
                System.out.println("线程名" + thread.getName() + "线程状态" +thread.getState());
            }
        });

        System.out.println("线程名" + threadTest.getName() + "线程状态" +threadTest.getState());

        threadTest.start();

        System.out.println("线程名" + thread.getName() + "线程状态" +thread.getState());
        System.out.println("线程名" + threadTest.getName() + "线程状态" +threadTest.getState());
    }
}

打印日志1:

线程名Thread-0线程状态NEW
线程名Thread-0线程状态RUNNABLE
线程名Thread-1线程状态NEW
线程名Thread-0线程状态TERMINATED
线程名Thread-1线程状态RUNNABLE
线程名Thread-0线程状态TERMINATED

打印日志2:

线程名Thread-0线程状态NEW
线程名Thread-0线程状态RUNNABLE
线程名Thread-1线程状态NEW
线程名Thread-0线程状态RUNNABLE
线程名Thread-1线程状态RUNNABLE
线程名Thread-0线程状态RUNNABLE

public class ThreadTestTwo {

    public static void main(String[] args) {
        Thread thread = new Thread(new Runnable() {

            @Override
            public void run() {
                for (int i = 0; i < 1000000000; i++) {

                }

            }
        });

        System.out.println("线程名" + thread.getName() + "线程状态"
                + thread.getState());

        thread.start();

        System.out.println("线程名" + thread.getName() + "线程状态"
                + thread.getState());

        try {
            Thread.sleep(1);
        } catch (InterruptedException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }

        System.out.println("线程名" + thread.getName() + "线程状态"
                + thread.getState());
    }
}
 

打印日志:

线程名Thread-0线程状态NEW
线程名Thread-0线程状态RUNNABLE
线程名Thread-0线程状态RUNNABLE

我来为大家分析一下这几个日志:
大家可以看到第一个线程就是thread线程,在Thread.start()方法调用之前是这个线程的状态是New(新建状态),在线程
Thread.start()方法调用之后线程的状态为Runnbale(就绪状态),在任务执行完之后状态变为Terimal(终止状态),大家可能发
现打印日志1和打印日志2略有不同,因为当线程threadTest的启动了之后,thread的任务有没有执行完成其实是一个未知不可确定的事情。这个
测试代码中还有一个知识点,大家有没有发现最后日志打印结果显示打印的最后日志竟然是Thread-0,很多人要问了最后一个日志不应该是
threadTest(Thread-1)么,其实不是因为threadTest的这个是在主线程中执行的,而有一个打印是在threadTest方法中
的,所以threadTest.run()方法中的打印日志才是最后一个,主线程的优先级是要比普通线程的优先级要高。但是不要去使用优先级去控制线程的
执行顺序,因为那并不可靠。但是因为优先级这部分使用的很少,也不是很重要,这里就不详细论述了,有兴趣的可以去看看。
通过上面这部分测试代码我们认识了线程这个类的三种状态,总结一下:
1、一个线程创建之后没有调用Thread.start()方法之前线程的状态是NEW
2、一个线程调用Thread.start()方法之后,线程的状态是RUNNABLE,无论线程是否在运行状态下线程,大家可以看第二个日志调用了Thread.sleep()方法线程的状态并没有改变可以得知
3、一个线程执行完任务之后,线程的状态就是Terimal(终结)

下面为大家讲述线程中的另外一个状态阻塞,阻塞状态又分三种(BLOCKED、WAITING、TIMED_WAITING),在讲阻塞状态之前又不可避免的先要为大家讲述一下synchronized这个关键字

时间: 2024-10-28 11:25:30

多线程JAVA篇(一)的相关文章

关于多线程的几个问题(面试小问题,Java篇)

面试官想考考我多线程方面的问题. 1.请说下线程与进程的关系. 答:<操作系统>中是这样说的 (1)一个线程只能属于一个进程,而一个进程可以有多个线程,但至少有一个线程.线程是操作系统可识别的最小执行和调度单位. (2)资源分配给进程,同一进程的所有线程共享该进程的所有资源.同一进程中的多个线程共享代码段(代码和常量),数据段(全局变量和静态变量),扩展段(堆存储).但是每个线程拥有自己的栈段,栈段又叫运行时段,用来存放所有局部变量和临时变量. (3)处理机分给线程,即真正在处理机上运行的是线

[转]有哪些值得关注的技术博客(Java篇)

有哪些值得关注的技术博客(Java篇) 大部分程序员在自学的道路上不知道走了多少坑,这个视频那个网站搞得自己晕头转向.对我个人来说我平常在学习的过程中喜欢看一些教程式的博客.这些博客的特点: 1.总结知识点相对比较全面 2.一般来说讲解知识点通俗易懂 3.路线比较清晰,不会有太多的冗余内容. 这样一来,对于自学的朋友来说,一些专业的博客不但大量的缩减了你得学习时间.提高了学习效率.更重要的是这些博客能培养你对编程的兴趣. 于是,这几期文章会主要推荐一些技术博客,目前计划打算主要分为: (已完) 

总结一下阿里云OSS的开发坑(Java篇)

一.序言 OSS(Object Storage Service)是阿里云提供的一款云存储服务,具有海量.安全.低成本.高可靠的特点. 由于客户选择了OSS,我们作为开发方也开始接触它.在实际开发过程中遇到了各种各样的坑,经自己多次实践及阿里技术人员的协助,终得以完成任务. 阿里方面为OSS提供了多种语言的开发接口,我们用到了其中两种:Java和C/C++.本文为Java篇,C/C++的将在另一篇给出. 二.OSS的一些概念 EndPoint, accessKeyID, accessKeySecr

秒杀多线程第一篇 多线程笔试面试题汇总 ZZ 【多线程】

http://blog.csdn.net/morewindows/article/details/7392749 系列前言 本系列是本人参加微软亚洲研究院,腾讯研究院,迅雷面试时整理的,另外也加入一些其它IT公司如百度,阿里巴巴的笔试面试题目,因此具有很强的针对性.系列中不但会详细讲解多线程同步互斥的各种“招式”,而且会进一步的讲解多线程同步互斥的“内功心法”.有了“招式”和“内功心法”,相信你也能对多线程挥洒自如,在笔试面试中顺利的秒杀多线程试题. ----------------------

秒杀多线程第一篇 多线程笔试面试题汇总

版权声明:本文为博主原创文章,未经博主允许不得转载. 目录(?)[+] 系列前言 本系列是本人参加微软亚洲研究院,腾讯研究院,迅雷面试时整理的,另外也加入一些其它IT公司如百度,阿里巴巴的笔试面试题目,因此具有很强的针对性.系列中不但会详细讲解多线程同步互斥的各种“招式”,而且会进一步的讲解多线程同步互斥的“内功心法”.有了“招式”和“内功心法”,相信你也能对多线程挥洒自如,在笔试面试中顺利的秒杀多线程试题. -------------------------------------华丽的分割线

Linux C 程序设计多线程基础篇

   Linux C 程序设计多线程基础篇 题记:因为 Linux 网络入侵检测系统的设计与实现希望使用多线程,因此希望系统的学习一下 Linux C程序设计多线程的知识 注意事项:因为 pthraed 库不是 Linux 系统默认的库,因此在进行多线程开发的时候,需要加上头文件#include <pthread.h>,编译时要加参数 -lpthread;了:gcc thread.c -o thread -lpthread. 进程和线程: 进程是程序执行,资源分配的基本单位,每个进程都拥有自己

关于一些设计模式(面试小问题,Java篇)

今天在某公司(不透露了)写了一套Java面试题.有个题大概是这样的. Which design pattern used in Java.lang.Runtime? 就是说java.lang.Runtime里,用了什么设计模式 还有java.utils.collection里用了什么设计模式. 当时由于对这冷门知识了解的不够多,而且api也读的少,所以一时答不上来. 回到家搜了下. 答: Runtiome里 单例模式. 1)  每一个Java程序都有一个Runtime类的单一实例. 2)  通过

优秀的编程风格(Java篇)——高薪必看

今天突发奇想,对编码习惯和编程风格很感兴趣,于是乎,找了一下关于编程风格(Java篇)的资料,希望对爱好编码或者开始学习编码的同学有帮助! 来自<The Elements of Java Style>-<Java编程风格>一书,值得一读的书籍,会让你在细节上节省很多时间,合作之间更加愉快! 好处不多说了,但是有几个原则如下: 1.保持原有风格 2.坚持最小惊奇原则 3.第一次就做对 4.记录所有非规范行为 格式规范: 1.缩进嵌套的代码:在每个代码块和嵌套中加入缩进,缩进代码,加强

事件驱动模型实例详解(Java篇)

或许每个软件从业者都有从学习控制台应用程序到学习可视化编程的转变过程,控制台应用程序的优点在于可以方便的练习某个语言的语法和开发习惯(如.net和java),而可视化编程的学习又可以非常方便开发出各类人机对话界面(HMI).可视化编程或许是一个初学者开始对软件感兴趣的开始,也可能是一个软件学习的里程碑点,因为我们可以使用各类软件集成开发环境(IDE)方便的在现成的界面窗口上拖放各类组件(Component),这类组件包括我们常见的按钮(Button),单选按钮(Radio Button),复选框