java多线程
java语音的一个优势就是使用多线程比较简单
一般操作系统都是支持同时运行多个任务,一个任务通常就是一个[程序],每个运行的程序都被称为一个[进程]
程序内容通常也同时运行多个任务,那么每个任务称为[线程]
程序: 指令+数据的byte序列, 比如:qq.exe
进程: 正在运行的程序,是程序动态运行的过程(操作系统级别的任务,运行在内存中)
线程: 在进程内部,并发运行的过程(程序级别的任务)
并发: 进程是并发运行的,线程也是并发运行的,OS将时间划分为很多时间片段(时间片),尽可能均匀的分配给
每个正在执行的任务,微观上进程或线程都是走走停停的,宏观上是都在运行的,这种现象称之为并发,但
不是绝对意义上的同时运行.
===========================================================================================
java中的线程创建
Thread类
线程类Thread包含一个可执行的过程(线程体):run方法
创建一个线程的步骤:
1.继承Thread类
2.重写run()方法,实现线程体
3.创建这个线程的实例
4.调用这个线程实例的[start()]方法,启动线程
线程的状态
线程的5个状态
NEW 新建的线程
当使用NEW关键字创建一个线程后,该线程就处于新建状态,此时线程还未启动
RUNNABLE 可运行状态(就绪状态)
当线程处于runnnable状态时,那么此线程可随时获得CPU时间片段来执行任务
RUNNING 正在运行状态
此时该线程已经获得CPU时间片段并被CPU执行(调用其run方法).若有一个CPU,
那么同一时间只有一个线程处于running状态,若有两个cpu那么同一时间就有两
个线程处于running状态,以此类推,多核cpu有同样的效果.
调用yield()方法,可以主动放弃当前的cpu时间,回到runnable状态,等待下次cpu时间
block 阻塞状态
当线程有以下情况会发生阻塞:
线程调用了sleep()方法主动放弃占用cpu资源
线程调用了一个阻塞时I/O方法:例如:获取键盘输入信息
那么在获取键盘输入信息方法返回前,此线程阻塞其他会引发阻塞的方法等等....
当线程处于阻塞状态时,其他线程就有机会执行任务了,但需要注意,当线程的
阻塞状态结束时,该线程会进入[runnable]状态,而不是[running]
DEAD 死亡状态
当run()方法执行完毕,线程进入死亡状态,该线程等待被GC回收(若此线程无引用)
===============================================================================================
线程的状态管理
1.让出CPU时间:yield()
当前线程让出CPU时间(主动从running状态回到runnable状态)
2.休眠Thread.sleep(time)
当前线程进入阻塞状态,阻塞时间明确(参数给定,毫秒级).阻塞结束后自动回到[runnable]状态.在睡眠阻塞
过程中若打断这个线程的阻塞会引发异常InterruptedException
===============================================================================================
线程常用的属性和方法
线程优先级
t.setPriority(int)
默认有10个优先级,优先级高的线程获得执行(进入running状态)的机会多,但是注意!![机会的多少不能通过代码干涉]
线程默认的优先级为:5
优先级常量:
Thread.MAX_PRIORITY最高优先级 10
Thread.MIN_PRIORITY最低优先级 1
后台线程(守护线程,精灵线程)
t.setDaemon(true)方法将线程设置为后台线程,默认情况下,线程的这个属性为false;
java进程结束:当前进程中所有[前台线程]都结束时,进行结束也就是说,当所有前台线程都结束后,无论后台线程是否还
活着,都要被强制停止
设置后台线程的方法setDaemon(boolean)要在start()方法[执行前]被调用.
获得线程名
getName()
获得当前线程
Thread t=Thread.currentThread();
=================================================================================================
创建线程的两种方式
继承Thread类,实现Runnable接口(线程体)
Java语言不允许一个类继承多个类,如果某个类已经声明成继承其他类,那么它将不可以继承Thread类,所以要使用Runnable
1:继承Thread类
实现步骤:
1.继承Thread类
2.重写run()方法(线程体:线程要执行的任务内容)
3.创建对象,启动线程
2:实现runnable接口
实现步骤:
1.声明一个类并实现Runnble接口,重写run()方法
2.创建该类的实例
3.创建Thread类的实例,使用Thread的一个重载构造方法
创建实例:Thread(Runnble runnable),在创建Thread实例的同时,将Runnable的实例传入
4.调用start()方法启动线程
=================================================================================================
Sleep阻塞打断唤醒
IO阻塞:通常IO操作都会发生阻塞
异步:并发的,各干各的 (一般发生在多线程)
同步:步调一致,有先后顺序的 (一般发生在单线程)
java语音的一个优势就是使用多线程比较简单
一般操作系统都是支持同时运行多个任务,一个任务通常就是一个[程序],每个运行的程序都被称为一个[进程]
程序内容通常也同时运行多个任务,那么每个任务称为[线程]
程序: 指令+数据的byte序列, 比如:qq.exe
进程: 正在运行的程序,是程序动态运行的过程(操作系统级别的任务,运行在内存中)
线程: 在进程内部,并发运行的过程(程序级别的任务)
并发: 进程是并发运行的,线程也是并发运行的,OS将时间划分为很多时间片段(时间片),尽可能均匀的分配给
每个正在执行的任务,微观上进程或线程都是走走停停的,宏观上是都在运行的,这种现象称之为并发,但
不是绝对意义上的同时运行.
===========================================================================================
java中的线程创建
Thread类
线程类Thread包含一个可执行的过程(线程体):run方法
创建一个线程的步骤:
1.继承Thread类
2.重写run()方法,实现线程体
3.创建这个线程的实例
4.调用这个线程实例的[start()]方法,启动线程
线程的状态
线程的5个状态
NEW 新建的线程
当使用NEW关键字创建一个线程后,该线程就处于新建状态,此时线程还未启动
RUNNABLE 可运行状态(就绪状态)
当线程处于runnnable状态时,那么此线程可随时获得CPU时间片段来执行任务
RUNNING 正在运行状态
此时该线程已经获得CPU时间片段并被CPU执行(调用其run方法).若有一个CPU,
那么同一时间只有一个线程处于running状态,若有两个cpu那么同一时间就有两
个线程处于running状态,以此类推,多核cpu有同样的效果.
调用yield()方法,可以主动放弃当前的cpu时间,回到runnable状态,等待下次cpu时间
block 阻塞状态
当线程有以下情况会发生阻塞:
线程调用了sleep()方法主动放弃占用cpu资源
线程调用了一个阻塞时I/O方法:例如:获取键盘输入信息
那么在获取键盘输入信息方法返回前,此线程阻塞其他会引发阻塞的方法等等....
当线程处于阻塞状态时,其他线程就有机会执行任务了,但需要注意,当线程的
阻塞状态结束时,该线程会进入[runnable]状态,而不是[running]
DEAD 死亡状态
当run()方法执行完毕,线程进入死亡状态,该线程等待被GC回收(若此线程无引用)
===============================================================================================
线程的状态管理
1.让出CPU时间:yield()
当前线程让出CPU时间(主动从running状态回到runnable状态)
2.休眠Thread.sleep(time)
当前线程进入阻塞状态,阻塞时间明确(参数给定,毫秒级).阻塞结束后自动回到[runnable]状态.在睡眠阻塞
过程中若打断这个线程的阻塞会引发异常InterruptedException
===============================================================================================
线程常用的属性和方法
线程优先级
t.setPriority(int)
默认有10个优先级,优先级高的线程获得执行(进入running状态)的机会多,但是注意!![机会的多少不能通过代码干涉]
线程默认的优先级为:5
优先级常量:
Thread.MAX_PRIORITY最高优先级 10
Thread.MIN_PRIORITY最低优先级 1
后台线程(守护线程,精灵线程)
t.setDaemon(true)方法将线程设置为后台线程,默认情况下,线程的这个属性为false;
java进程结束:当前进程中所有[前台线程]都结束时,进行结束也就是说,当所有前台线程都结束后,无论后台线程是否还
活着,都要被强制停止
设置后台线程的方法setDaemon(boolean)要在start()方法[执行前]被调用.
获得线程名
getName()
获得当前线程
Thread t=Thread.currentThread();
=================================================================================================
创建线程的两种方式
继承Thread类,实现Runnable接口(线程体)
Java语言不允许一个类继承多个类,如果某个类已经声明成继承其他类,那么它将不可以继承Thread类,所以要使用Runnable
1:继承Thread类
实现步骤:
1.继承Thread类
2.重写run()方法(线程体:线程要执行的任务内容)
3.创建对象,启动线程
2:实现runnable接口
实现步骤:
1.声明一个类并实现Runnble接口,重写run()方法
2.创建该类的实例
3.创建Thread类的实例,使用Thread的一个重载构造方法
创建实例:Thread(Runnble runnable),在创建Thread实例的同时,将Runnable的实例传入
4.调用start()方法启动线程
=================================================================================================
Sleep阻塞打断唤醒
IO阻塞:通常IO操作都会发生阻塞
=================================================
线程并发安全问题
多线程并发访问同一个临界资源时候会发生[线程并发安全问题].如果保证多线程同步访问同一资源,就可以解决此问题.
常见的临界资源:
多线程共享一个实例变量
静态共用变量
线程安全锁(同步锁,互斥锁(被锁的方法不能同执行)):synchronized(关键字) 的两种定义方式
1.声明方法时加入:public synchronized void xxx(){}
2.同步语句块:synchronized(<任意对象>){}
同步锁是共有的,多个线程应使用同一个锁.(上锁对象为同一个)
我们把一次只允许一个线程使用的共享资源称为临界资源,而在每个进程中访问临界资源的程序段称为临界区
=============================================================================================
异步:并发的,各干各的 (一般发生在多线程)
同步:步调一致,有先后顺序的 (一般发生在单线程)