程序、进程与多线程
一.概念
程序: 是指令的集合,代码的集合
进程: 是动态的概念,当程序在执行时,系统分配进程;
多线程: 是在同一进程下,充分利用资源 ,多条执行路径,共享资源 (cpu data code)。
进程和线程的区别
进程: 作为资源分配的最小单位
1.系统在运行的时候会为每个进程分配不同的内存区域.
2.在一个进程当中只有一个线程的称之为单线程, 如果在一个进程当中存在多个线程,则执行过程不是一条线的,而是多条线的共同完成的, 即多线程.
3.每一个进程都有独立的代码和数据空间,进程间的切换会有较大的开销
线程: 作为CPU调度和执行的最小单位
1.线程所用的资源是它所属进程的资源,除了CPU外不会为线程分配内存. 并且线程组只能共享资源.
2.线程是进程的一部分,所以有时候会被称为轻量级进程或者轻权进程.
3.同一类线程共享代码和数据空间, 每一个线程都有独立的运行栈和程序计数器.多个线程之间切换开销小.
二 . 线程的开启方式
1.继承Thread类,重写run()方法.
创建子类对象,调用start()方法,开启多线程
2.实现Runnable接口,重写run()方法
Thread类做代理,调用Thread类中的start方法开启线程
优点: 1避免了单继承的局限性. 2 实现了资源共享
3. 实现Callable接口,重写call()方法—了解就好
优点:可以有返回值,可以抛出异常
缺点:使用复杂
注意: 继承和实现这两种方法开启线程用的比较多. 其中实现用的最多.
三 线程的状态
新生状态: new线程对象的时候,这个线程处于新生状态
就绪状态: 调用start()方法,线程进入就绪状态,进入到就绪队列,进入就绪状态代表线程有能力执行,但是要等到cpu调用,分配时间片才能执行
运行状态: 当前cpu调度,分配时间片给就绪状态的线程,当前线程执行
阻塞状态: sleep…
终止状态: 现成饭结束
注意:
A.如果线程一旦进入到阻塞状态不会直接进入运行状态,阻塞状态解除要进入到就绪状态
B. 线程一旦结束,无法恢复,如果重新开启,也是一个新的线程
1.如何控制线程的终止:
A.调用stop(),destory(),已过时,不推荐
B.线程正常执行结束
C.添加标识控制
2.进入线程就绪状态的几种情况:
A.start()方法
B.yield 礼让线程
1.如果当前线程调用yield方法,会直接进入到就绪状态
A.线程之前切换
B.解除阻塞状态,线程进入到就绪状态
3.进入线程阻塞状态的几种情况:
A.sleep方法—>sleep延迟:
1.放大问题的可能性. 2. 模拟网络延迟
B.join方法—>插队
1.插入后运行该线程,被插入的线程被阻塞 直到该线程结束后再返回到就绪位置 然后再 开始运行
C.wait方法
D.IO操作
4.查看线程状态
通过Thread类内部的getState()方法 返回该线程的状态…返回值为Thread.State
5.线程的优先级
A.void setPriority(int newPriority) 更改线程的优先级
B.int getPriority() 返回线程的优先级
1~10表示 1是最小 10是最大 默认是5
MIN_PRIORITY 最小, NORM_PRIORITY 默认, MAX_PRIORITY 最大
四 线程安全问题
问题的产生原因: 多个线程同时操作同一份资源的时候,可能会发生线程不安全问题
控制线程的安全: 加锁 synchronized —同步
同步方法: 在方法上面加锁
同步静态方法
同步成员方法
同步块: synchronized(){}
锁this: 锁this就是锁对象,所对象会锁住这个对象中的所有成员(资源),如果只想锁住其中的某个资源,可以只锁这个资源
锁资源: 一般就是指成员属性,锁一定要锁不变的内容,对象的地址永远不变,自定义的引用数据类型肯定能锁住
锁类: 锁类,这个类的所有对象都被锁住了
注意: 锁必须是锁不变得内容, 锁的范围太大会效率比较低 锁的范围太小,容易锁不住.