大刀EZ

  博客园 :: 首页 :: 新随笔 :: 联系 :: 订阅 :: 管理 ::

(事先声明:该文章并非完全是我自己的产出,更多的是我个人在看到资料后通过理解并记录下来,作为自己阅读后的一个笔记;我现在试图对自己多年工作中的知识点做一个回顾,并进行归类总结)

(此文参考<Java核心技术36讲>第17讲)

 

线程与进程

进程是操作系统层面的运行时对应的具体应用程序,用户启动一个应用程序就会运行一个或者多个进程。

线程是应用程序进程里面的,更加细粒度的实例,线程对用户而言是透明的,一个进程会包含一个或者多线程来实现程序的各种功能。其由开发人员在编写代码时定义,并由系统进行调度运行。

 

在早期的JVM设计中 (1.2),线程的实现是与虚拟机相关的,且于JVM自身来调度(Green thread),在现在的版本中, java线程基本都是1对1映射到操作系统内核线程了,由OS进行调度。

还有一种后台运行的称为守护线程, 当应用需要一个长期驻留的服务程序,但不希望其影响应用退出,就可以设置为守护线程;JVM发现只有守护线程存在时,进程结束。

 

线程包含什么

从操作系统的角度,线程是系统调试的最小单元,操作系统对不同任务的切换,就是在线程上完成的,线程包含: 栈(Stack), 寄存器(Register),本地存储(Thread Local)。但其和进程内其它线程共享文件描述符,虚拟地址空间等。

(补充:  更详细的线程结构和jvm内部)

 

线程生命周期的不同状态:

New: 线程被新建出来还没有真正启动执行。

Runnable(就绪): 表示线程已经在JVM中执行了,可能是正在运行,也可能是在等待CPU调度。

Blocked(阻塞): 表示线程在等待锁,如:线程试图通过synchronized去获取某个锁时,该锁已经被其它线程独占了,那当前线程就会进入此状态。

WAITING: 线程进行等待状态,需要其它线程唤醒(notify),如:当前线程在检测到需要的资源还不可用时,主动执行wait()。

TIMED_WAIT: 与上面相似,但带有超时条件。

Terminated: 终止,不管是意外退出还是正常执行结束。

 

线程的几种使用

1. 直接继承自Thread并且实现任务执行

    public void startNewThread() {
        new Thread(() ->  {
                // excute task, we override the method Thread.run()
            }).start();  //start the thread
    }

 

2. 实现Runnable 

实现Runnable接口的好处在于可以绕过java只能单一继承的限制(使用Thread的话,就不能继承其它类了), 这样可以更灵活的组织代码结构了。也可以把Runnable提交给并发库中的Executor框架使用。

        Runnable task = new Runnable() {
            @Override
            public void run() {
                // implement the task
            }
        };
        
        new Thread(task).start();  //start the thread

 

3.使用Executor框架

可以无须关心Thread的创建和管理,并且可以通Future来取得返回结果.

        Runnable task = new Runnable() {
            @Override
            public void run() {
                // implement the task
            }
        };

        Future result = Executors.newFixedThreadPool(1).submit(task);

 

posted on 2019-04-02 00:23  大刀EZ  阅读(115)  评论(0)    收藏  举报