1、进程:在操作系统上一段静态程序代码的执行过程
例如:我们自己使用Java程序编写了一个音乐播放器,就相当于一段静态代码),然后我们将这段静态代码在操作系统上执行,这个操作系统上就会有音乐播放器的执行进程
多进程:在操作系统上同时执行多个静态程序代码
例如:在操作系统上运行了音乐播放器,与此同时我们又打开了一个视频播放器
注意:进程是以依赖于操作系统的,进程和进程之间的交互很难实现
多进程是处理并发情况的,提高效率
2、线程:在同一个进程中可能会出现多条不同的执行线索共同工作的现象,把同一个进程中的其中一个执行线索就叫线程。
例如:打开视频播放器播放电影(进程),在这播放器中不仅有画面,声音,还有中文字幕。播放电影的时候画面,声音,中文字幕就是一个线程,
多线程:在同一进程中出现多条执行线索共同工作的情况。
给人的感觉是几件事情同时进行这是错觉。在同一时刻,只能有一条线程在运行,Cpu会高速切换线程(速度很快)
线程是依赖于进程的(没有进程就没有线程)。
线程执行完毕,进程不一定执行完毕。
进程结束,该进程中的所有线程也就结束了。
3、Java中的多线程
1、每个Java程序都有一个默认的主线程(把主方法执行的线程叫主线程)
2、一个Java程序运行起来,至少有两个线程已经在运行了(1、主线程2、垃圾自动回收线程),必不可少
创建线程的两种方法:
4、在Java中创建线程的方法有两种
1、继承Thread类(继承了Run()方法)Thread类属于Java.long包(Java.long包会自动导入)
1.1继承Thread类
1.2重写Thread类中的run()方法。(需要由线程执行的Java代码写入到run()方法中)
1.3启动线程(直接调用run()方法,不是启动线程的方式),启动线程使用start(),它是Thread类的
2、实现Runnable接口(Java.long包),只有一个Run()方法
Thread实现了Runnable接口
3、比较
1、implement Runnable, extends Thread
2、implement Runnable先创建目标对象,后创建线程对象
extends Thread直接使用线程对象调用start()对象
3、implementRunnable可以做到资源共享(操作方式比较优秀)
extends Thread不可以做到资源共享
4、都需要重写run()方法
5、线程中的常用方法方法
1、static current():得到当前正在运行的线程对象
2、static sleep():线程休眠指定的时间,会有异常抛出
2、getName():获得当前线程名称
3、setName():设置线程名称
4、int getPriority():得到线程的优先级
5、setPriority():设置线程的优先级
6、isAlive():判断线程是否正在运行,satrt()方法之后调用返回值为true
7、sleep(long haomiao):表示当前线程休眠
8、join():A线程在执行过程中把cpu资源给B线程,直到B线程运行结束A线程才继续执行(下载线程)
9、interrupt():唤醒当前休眠的线程
//一下不是线程类中的方法,是Object中的方法
10、wait():暂停线程执行
11、notify()/notifyAll():唤醒等待池中的一条/所有线程
6、线程的调度和线程的优先级
1、在只有一个处理器的机器上,在同一时刻只能处理一个动作
2、java的线程是抢占式的,但不一定是分时的
3、处于准备就绪的线程(可运行)首先进入就绪队列中等待CPU资源,同一时刻就绪队列中的线程可能有多个。
4、 jvm 的线程调度器负责管理线程,他把线程的优先级分为十个级别,Thread.NORM_PRIORITY,数字越大,优先级越高。线程可以通过void setPriority(int newp)方法设置。有些操作系统只识别1、5、10。优先级高只是运行的机会高。
关于线程调度:对于多线程的执行,不仅不同机器的执行结果不同,而且在同一机器上运行多次同一程序产生的结果也不同,永远不要期望一个线程会在另一个线程之前做某些操作,除非使用了同步以强制一个特定的执行程序。
千万不要通过设置线程优先级的方式来设置某条线程先被执行。
7、关于线程名称的设置和获取
1、继承Thread类
1、设置线程名称的方法
1、构造方法赋值
2、setName(Stringname)
2、得到线程名称的方法
getName()
2、实现Runnable接口
1、设置线程的名称
1、Thread类的构造方法,Thread th= new Thread(trage,”线程名称”)
2、setName(String name)
2、得到线程名称的方法
getName()
8、线程的生命周期
1、新建状态
2、就绪状态
3、运行状态
4、阻塞状态
5、死亡状态
线程生命周期图
8、run()方法的局部变量
不同线程中run()方法的局部变量互不干扰
一个线程改变了自己run()方法的局部变量的值不会影响其他线程中run()方法中的局部变量。
9、在主线程中可以启动其他线程,在其他线程中也可以启动其他线程
10、守护线程
1、线程一般默认是普通线程,非守护线程,也叫用户线程
2、使用setDaemon()可以将用户线程设置为守护线程。也叫精灵线程
3、当程序中所有的用户线程执行结束时,就算守护线程中还有需要执行的语句,守护线程也会立刻结束运行
4、一个线程必须在start()方法之前设置自己是否是守护线程
5、java程序是在所有的用户线程执行完之后退出的。
Publicclass Myclass implement Runnable(){
Publicvoid run(){
}
}
Myclass my = newMyclass()
Thread th1 = newThread(my)//线程对象,用户线程
th1.setDeamon(true)//守护线程
th1.start()
11、线程同步(线程安全),是一种解决方法
1、线程同步:当程序中使用两个或者多个线程的时候,可能会发生多个线程放问题一个资源的时候,只允许两个或者多个线程中的一个线程访问资源,其他的线程必须等待,必须保证一个共享资源只能被一条线程访问。(会造成数据不一致的情况)
2、在Java中为保证共享资源的完整性,引入了互斥锁概念,互斥锁保证在同一时间只能有一个线程访问该对象。
3、当对象使用synchronized修饰的时候,表明该对象启动互斥锁机制,在任何时刻只能有一个线程访问该对象,即使线程处于阻塞情况,对象被锁定的状态也不会被解除,其他线程仍不能访问该对象。
11、Java中如何实现线程同步(火车站买票的方式)
使用synchronized关键字
实现同步的方式有几种:
1、同步代码块:
格式:synchronized(同步对象){
需要被同步执行的Java代码
}
2、同步方法:
格式:public synchronized void MyThread(参数列表){
需要被同步执行的Java代码
}
3、缺点:加了线程同步,代码的执行效率就会降低。
12、死锁:线程的相互等待