• 并发基础(一) 线程介绍


    一、线程的简介

    线程,有时被称为轻量级进程(Lightweight Process,LWP),是程序执行流的最小单元。一个标准的线程由线程ID,当前指令指针(PC),寄存器集合和堆栈组成。另外,线程是进程中的一个实体,是被系统独立调度和分派的基本单位,线程自己不拥有系统资源,只拥有一点儿在运行中必不可少的资源,但它可与同属一个进程的其它线程共享进程所拥有的全部资源。一个应用程序可以看做是一个进程,一个进程可以创建多个线程,进程的任务就是交给这些线程来完成。

    线程基础知识点可以总结为几点:

    1. 线程是程序中的执行线程。java虚拟机允许应用程序并发地运行多个执行线程。
    2. 每个线程都有一个优先级,高优先级线程的执行优先于低级优先级线程。但不应该通过设置线程优先级的方式来安排线程的执行顺序,后续将会细说。
    3. 每个线程都可以或者不标志为一个守护线程。即在java中,线程分为两类:用户线程 和 守护线程。
    4. 当java虚拟机启动时,都会有一个非守护线程(即用户线程)启动运行。这个线程通常是调用指定类的main方法。简单来说,当你执行一个类的main方法时,其实是作为一个线程在运行,即为main线程。
    5. 线程在操作系统中是不拥有资源, 线程是共享进程的资源。即属于同一个进程的多个线程之间是对资源可能要进行互斥访问。这就要涉及到锁的概念。同时在JVM中,除了用锁来解决并发的问题外,还可以让每个线程拥有私有资源---线程副本(ThreadLocal),这样,线程就不需要竞争资源。

    二、用户线程与守护线程
    守护线程:
          守护线程则是用来服务用户线程的,可以简单理解为后台运行线程。(操作系统里面是没有所谓的守护线程的概念,只有守护进程一说,但是Java语言机制是构建在JVM的基础之上的,意思是Java平台把操作系统的底层给屏蔽起来,所以它可以在它自己的虚拟的平台里面构造出对 自己有利的机制,而语言或者说平台的设计者多多少少是受到Unix思想的影响,而守护线程机制又是对JVM这样的平台凑合,于是守护线程应运而生);
        守护线程使用的情况较少,但并非无用,举例来说,JVM的垃圾回收、内存管理等线程都是守护线程。还有就是在做数据库应用时候,使用的数据库连接池,连接池本身也包含着很多后台线程,监控连接个数、超时时间、状态等等。

    注意:
    1、JRE判断程序是否执行结束的标准是所有的前台执线程行完毕了,而不管后台线程的状态,因此,在使用后台线程候一定要注意这个问题。
    也就是说,当进程中所有非守护线程已结束或退出时,即使仍有守护线程在运行,进程依旧会结束。
    也就是说,当程序结束时,守护线程有可能依然未退出。
    2、基于第一点,守护线程是不能用于逻辑业务计算的,否则很可能还没有计算出结果,程序就结束了。

    守护线程的设置:
      默认情况下,创建的线程默认是用户线程。如果要将此线程变成守护线程,则要在线程启动前调用Thread 类的 setDemo()方法,标志为守护线程。

    setDemo()方法详解:

    public final void setDaemon(boolean on)将该线程标记为守护线程或用户线程。当正在运行的线程都是守护线程时,Java 虚拟机退出。    
      该方法必须在启动线程前调用。    
    
      该方法首先调用该线程的 checkAccess 方法,且不带任何参数。这可能抛出 SecurityException(在当前线程中)。    
    
    
      参数: 
        on - 如果为 true,则将该线程标记为守护线程。    
      抛出:    
        IllegalThreadStateException - 如果该线程处于活动状态。    
        SecurityException - 如果当前线程无法修改该线程。 
      另请参见: 
        isDaemon(), checkAccess()
    

    例子:

    //这是一个很简单的线程,没有指定任何的任务
    	Thread t =new Thread();
    	//判断刚创建的线程t是不是守护线程
    	if(t.isDaemon()){
    		System.out.println("线程是守护线程");
    	}else{
    		System.out.println("线程是用户线程");
    	}
    	
    	//将线程t设置为 守护线程
    	t.setDaemon(true);
    	//线程启动,注意:必须在线程启动前调用setDaemon()才有效
    	t.start();
    

    运行结果:
        线程是用户线程

  • 相关阅读:
    如何更改Web Service部署生成的App_Code.dll的名称
    Orcas中C#语言的新特性:自动属性,对象初始化器,和集合初始化器
    驗證類javascript
    多线程下WinForm开发应该注意哪些问题?
    把表从Access2007导出到Sql Server
    面向对象模型的四种核心技术
    ASP常用代碼二
    熊猫烧香代码
    简繁体互转代码
    上班人员必读:“五险一金”详解!
  • 原文地址:https://www.cnblogs.com/jinggod/p/8484674.html
Copyright © 2020-2023  润新知