在编程中,很多时候,我们需要计算机同时处理多件事情,例如说,就拿我相对最熟悉的web服务来说,web程序必须支持多用户访问,要不然如果你的用户只能支持一个用户在线访问,其他用户只能以排队的形式等待,估计你的网站没有谁愿意使用。

多线程提供给我们这样一种手段:同个时间内,我们可以运行多个程序路径,当然,同一个时间段这个说法只是说在我们人这个尺度来说是同时的,cpu其实是串行交替执行各个线程的代码路径的(单核cpu,多核的话估计是正真的并行)。多线程使得我们可以充分利用cpu的资源,毕竟cpu的运算速度太快了。下面对前段时间对多线程的学习收获进行简单梳理和总结。

一、线程的概念

  这个,不多说,只是为了内容完整性说说个人理解:代码执行上理解,没条线程代表一个代码执行路径;操作系统上面说,线程是操作系统可以调度和分配资源的最小单位。下面简单看个丑图吧,它大概说明了线程是个什么东西:

所以,线程就是在原有程序的基础上,新开了一条(多条)执行路径,而且新开的路径和原来的路径会同时执行

二、java中的线程

  1、如何实现多线程?

   A、实现接口,废话不多说,上代码先:

//多线程实现方式一:实现接口
class ThreadTest1 implements Runnable{
public void run() {
System.out.println("我是程执新执行路径的入口run方法");
}
}
//下面这个测试类展示了我们如何调用对应的实现了Runnable接口的类,从而实现多线程
public class ThreadStage {
public static void main(String[] args) {
//题外话:main也是条线程!它是java程序执行的入口
Thread thread = new Thread(new ThreadTest1());
thread.start();//start线程的开始执行的标记方法(当然,start方法执行了并不代表线程就执行了,后面具体说这个问题)
System.out.print("我是main方法的执行路径,其实我也只是一条线程");
} }

OK,这样就实现了程序的多线程,是不是炒鸡简单?在上面中,run方法就是相当于新路径的执行入口,所有该路径的执行代码都从这里执行开始,这里有个误区:新开一条线程是调用Thread的start方法,不是直接调用run方法!如果直接调用run方法,只是简单地在原有路径中串行执行run方法的代码,不会新开一条执行路径。

  B、另外一种方法就是继承Thread类,上代码:

//多线程实现方法二
class ThreadTest2 extends Thread{
//重写run方法即可
public void run(){
System.out.println("sleep");
try {
Thread.sleep(3000);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
System.out.println("我是新线程,是通过继承thread实现的新代码执行路径");
}
} //下面是对ThreadTest2中新开线程的示例
public class ThreadStage {
public static void main(String[] args) {
new ThreadTest2().start();//继承线程类的子类可以自己调用start方法直接开线程
System.out.println("我是main方法的执行路径,其实我也只是一条线程");
} }

废话就不多说了,代码也清楚展示了如何利用继承方法实现多线程了,要注意的还是上面那个问题:新开线程调用start方法,不能调用run方法!

  C、两种方法,用哪种?

    一般来说,用实现接口的方式,因为java不支持多继承。

三、线程的状态

  1、线程状态转换。具体状态名不一 一列出来了,先用下面的丑图说明线程从出生到死亡的整个过程吧:

ok,图上面大概说明了线程状态了,当然,具体的状态解释下面会详细总结。

  2、线程状态解释。

  A、首先,new Thread动作发出后,代表内存中新建了一个Thread类的对象,在内存层面为线程做好线程执行的准备工作;

  B、然后,调用start方法,这是,相当于告诉操作系统:该线程的所有准备工作已经完成,操作系统你可以来调度我啦,所以,start并不代表线程开始运行,它只是出于一个准备完成随时可以被操作系统调度这样一个状态而已;

  C、当在执行中遇到sleep,wait或者阻塞情形时,线程都会暂停执行,直到相应的条件满足或者其他线程再次激活线程,具体表现为:

    sleep时,线程会在设定好的时间过去后,退出sleep执行状态,回到类似于start方法刚执行的状态,等待操作系统调度;

    wait时,线程会处于等待状态,知道有某些线程调用一个叫做notifyAll(notify)方法时,线程等待状态才会退出,具体为什么要这个wait的状态后面的博客中会具体讨论;

    阻塞时,是由于外界条件不满足程序的执行条件而使得程序处于等待状态,等待外界条件满足之后,线程才会退出该状态。

  三种状态的具体区别大概如下:sleep保持程序锁定(不释放锁)而且自己控制什么时候退出该状态(通过时间设置);wait释放锁而且受其他线程控制才能再次进入执行状态(通过其他线程调用notify方法);阻塞不会释放锁而且只有满足条件时才会退出阻塞状态进入执行(例如申请的锁满足了),阻塞的状态改变依赖于外界条件或者说其他线程释放锁。

  D、当判处异常时或者提前遇到run方法体中的return或者线程执行完毕时,线程进入消亡状态,等待GC。

线程基础篇1总结 大概这么多先,后面会再陆续整理线程的同步问题!

    

java线程总结1--线程的一些概念基础以及线程状态的更多相关文章

  1. java线程(1)--概念基础

    参考:http://lavasoft.blog.51cto.com/62575/99150 http://blog.csdn.net/baby_newstar/article/details/6783 ...

  2. Java多线程开发系列之四:玩转多线程(线程的控制2)

    在上节的线程控制(详情点击这里)中,我们讲解了线程的等待join().守护线程.本节我们将会把剩下的线程控制内容一并讲完,主要内容有线程的睡眠.让步.优先级.挂起和恢复.停止等. 废话不多说,我们直接 ...

  3. 【Java基础】线程和并发机制

    前言 在Java中,线程是一个很关键的名词,也是很高频使用的一种资源.那么它的概念是什么呢,是如何定义的,用法又有哪些呢?为何说Android里只有一个主线程呢,什么是工作线程呢.线程又存在并发,并发 ...

  4. Java线程基础知识(状态、共享与协作)

    1.基础概念 CPU核心数和线程数的关系 核心数:线程数=1:1 ;使用了超线程技术后---> 1:2 CPU时间片轮转机制 又称RR调度,会导致上下文切换 什么是进程和线程 进程:程序运行资源 ...

  5. Python GUI之tkinter窗口视窗教程大集合(看这篇就够了) JAVA日志的前世今生 .NET MVC采用SignalR更新在线用户数 C#多线程编程系列(五)- 使用任务并行库 C#多线程编程系列(三)- 线程同步 C#多线程编程系列(二)- 线程基础 C#多线程编程系列(一)- 简介

    Python GUI之tkinter窗口视窗教程大集合(看这篇就够了) 一.前言 由于本篇文章较长,所以下面给出内容目录方便跳转阅读,当然也可以用博客页面最右侧的文章目录导航栏进行跳转查阅. 一.前言 ...

  6. JAVA基础之线程

    个人理解: 在相同的进程也就是运行同样的程序的前提下,线程越多效率越快!当然硬件也是个障碍!为了提高效率,可以多创建线程,但是也不是越多越好,这就需要了线程池进行管理!需要知道的线程实现的方法:继承T ...

  7. java基础(27):线程安全、线程同步、等待唤醒机制

    1. 多线程 如果有多个线程在同时运行,而这些线程可能会同时运行这段代码.程序每次运行结果和单线程运行的结果是一样的,而且其他的变量的值也和预期的是一样的,就是线程安全的. 我们通过一个案例,演示线程 ...

  8. java线程基础巩固---线程生命周期以及start方法源码剖析

    上篇中介绍了如何启动一个线程,通过调用start()方法才能创建并使用新线程,并且这个start()是非阻塞的,调用之后立马就返回的,实际上它是线程生命周期环节中的一种,所以这里阐述一下线程的一个完整 ...

  9. Java面试专题-多线程篇(2)- 锁和线程池

随机推荐

  1. vue.js 知识点(三)

    ---恢复内容开始--- vue和react相同,都是单项数据流,也就是只能从父组件流向子组件,但是因为根据引用的不同,子组件也是可以经过函数处理流向父组件的!这点跟react十分相似,但是也有不同: ...

  2. iis7下站点日志默认位置

    在iis6时,通过iis管理器的日志配置可以找到站点日志存储的位置. 但是在iis7下,iis管理器下的日志配置只能找到iis日志配置的主目录,但到底在哪个子目录,则无法直接获知.     后来在主日 ...

  3. ZooKeeper参数

    原文连接:https://www.cnblogs.com/skyl/p/4854553.html ZooKeeper参数调优   zookeeper的默认配置文件为zookeeper/conf/zoo ...

  4. Python自动发送HTML测试报告

    在我们做自动化测试的时候,执行完所有的测试用例,我们是希望马上得到结果的,那么我们不可能一直盯着去看,这个时候就需要引入邮件功能 1.首先我们使用一个python的第三方发邮件的库 yagmail g ...

  5. 963 AlvinZH打怪刷经验(背包DP大作战R)

    963 AlvinZH打怪刷经验 思路 这不是一道普通的01背包题.大家仔细观察数据的范围,可以发现如果按常理来的话,背包容量特别大,你也会TLE. 方法一:考虑01背包的一个常数优化----作用甚微 ...

  6. 【杂记】linux下各种软件安装方法(持续记录)

    1.安装jdk: 网上一堆说先从windows下压缩包,然后通过共享文件夹copy到linux系统里,然后解压安装,emmmmm 首先进入usr文件夹,新建java文件夹: mkdir java 直接 ...

  7. python全栈开发学习_day1_计算机五大组成部分及操作系统

    一.计算机五大组成部分: 1)五大组成: 1.控制器(指挥系统,用于控制其他计算机硬件的工作) 2.运算器(用于数学运算及逻辑运算) 3.存储器(寄存器,高速缓存,内存,磁盘(机械,固态),磁带) 4 ...

  8. redis的主从同步

    一.redis的主从操作流程 1. 准备三个redis配置文件 #进入redis的配置文件夹,准备好这几个文件,6379不用管,默认的,和这次操作无关 [root@qishi ~]# cd /etc/ ...

  9. Map.Entry使用详解

    1.Map.Entry说明 Map是java中的接口,Map.Entry是Map的一个内部接口. Map提供了一些常用方法,如keySet().entrySet()等方法,keySet()方法返回值是 ...

  10. Spark on YARN简介与运行wordcount(master、slave1和slave2)(博主推荐)

    前期博客 Spark on YARN模式的安装(spark-1.6.1-bin-hadoop2.6.tgz +hadoop-2.6.0.tar.gz)(master.slave1和slave2)(博主 ...