本帖最后由 心在左边跳 于 2015-7-6 16:31 编辑
线程概述进程:是正在执行中的程序。每个进程执行都有个执行顺序,该顺序是一个执行路径,或者叫一个控制单元。(进程标志执行内存空间) 线程:是进程中独立的控制单元,线程在控制进程执行。(多个线程抢占执行优先权,CPU执行谁,谁就运行。在同一时刻,只有一个程序运行,除了多核可以同时执行线程。CPU在快速切换,以达到同时运行效果)
一个进程之至少有个线程。
JVM 启动时会有个进程java.exe。该进程至少有个线程负责java程序执行。而且该线程运行的代码存在于main方法中。该线程称为主线程。
扩展:JVM起点不止一个线程,还有负责垃圾回收机制的线程。 创建线程-继承Thread类- 定义类,继承Thread
- 重写run()方法
- 调用线程start()方法。该方法2个作用,启动线程,JVM调用run方法。run和start特点为什么要覆盖run()方法?
Thread类用来描述线程:
该类定义一个功能,用来存储线程要运行的代码,该存储功能就是run()方法。
thread.start//开启线程并执行该线程的代码
thread.run//仅仅对象调用方法,而线程创建了,并没有运行。
线程的运行状态被创建---start()---运行----sleep or wait---冻结(放弃执行资格)----notify()-----临时阻塞状态 运行----stop or run结束---消亡 临时阻塞状态:具备运行资格,但没有执行权。 获取线程对象和名称线程都有自己的名称,Thread-编号,编号从0开始
getName()--setName() - class Test extends Thread {
- public Test(String name){
- super(name);
- }
- }
复制代码Thread.currentTread() //获取当前线程对象
局部变量在每个线程区域当中都有独立一份 声明Runnable接口创建线程的第二种方法:实现runnable接口 - 定义类实现Runnable接口
- 覆盖Runnable中run方法
- 通过Thread建立线程对象
- 将Runnable接口子类对象作为参数传递给Thread的构造函数
- 调用Thread的start开启线程调用Runnable接口子类的run方法。
- class Ticket implements Runnable {
- public void run(){
- }
- }
- Ticket t= Ticket();
- new Thread(t).start();
- new Thread(t).start();
复制代码实现方式和继承方式有什么区别?
实现方法避免了单继承的局限性,在定义线程时,建议使用实现方法。 多线程安全问题synchronized(对象){
需要被同步的代码
}
对象如同锁,当线程获取锁时,置锁的状态为false,不让其他线程进来,出来后,锁置为true。
弊端:多个线程需要判断锁,消耗资源。
好处:解决了多线程的安全问题。
- 明确哪些代码是多线程运行代码
- 明确共享数据
- 明确多线程运行代码中哪些语句是操作共享数据的。同步函数同步2种表现形式:同步函数,同步代码块。
让函数具备同步性
public synchronized void add(){}同步函数的锁是this同步函数被对象调用,那么函数有一个所属对象引用,就是this.所以同步函数使用的锁是this.
- public class Ticket implements Runnable {
- private int tick=1000;
- boolean flag=true;
- @Override
- public void run() {
- if (flag){
- while (true){
- synchronized (this) {
- if(tick>0){
- try{Thread.sleep(10);}catch (Exception e){e.printStackTrace();}
- System.out.println(Thread.currentThread().getName()+".....CODE....."+tick--);
- }
- }
- }}else {
- while (true){
- this.show();
- }
- }
- }
- public synchronized void show() {
- if(tick>0){
- try{Thread.sleep(10);}catch (Exception e){e.printStackTrace();}
- System.out.println(Thread.currentThread().getName()+".....SHOW....."+tick--);
- }
- }
- public static void main(String[]args){
- Ticket t = new Ticket();
- Thread t1= new Thread(t);
- Thread t2= new Thread(t);
- t1.start();
- try{Thread.sleep(1);}catch (Exception e){e.printStackTrace();}
- t.flag=false;
- t2.start();
- }
- }
复制代码 静态同步函数的锁是Class对象public static synchronized show()
静态方法中不可能有this,静态进内存时,内存没有本类对象,但一定有该类对应的字节码文件对象。类名.class 该对象的类型是Class.
静态同步方法,使用的锁是该方法所在类的字节码文件对象,类名.class 单例设计模式–懒汉式延迟加载的懒汉式 - class Single {
- private static Single s=null;
- private Single(){}
- public static Single getInstance(){
- if(s==null){//双重判定解决效率问题
- synchronized(Single.class){
- s=new Single();
- }
- }
- return s;
- }
- }
复制代码 死锁同步中嵌套同步,而锁不同 - class DeadLock implements Runnable {
- private boolean flag;
- public DeadLock(boolean flag) {
- this.flag=flag;
- }
- public void run(){
- if(flag){
- synchronized(MyLock.locka){
- System.out.println("if locka");
- synchronized(MyLock.lockb){
- System.out.println("if lockb");
- }
- }
- }else{
- synchronized(MyLock.lockb){
- System.out.println("else lockb");
- synchronized(MyLock.locka){
- System.out.println("else locka");
- }
- }
- }
- }
- public static void main(String[] args){
- Thread t1=new Thread(new DeadLock(true));
- Thread t2=new Thread(new DeadLock(false));
- t1.start();
- t2.start();
- }
- }
- class MyLock{
- public static Object locka=new Object();
- public static Object lockb=new Object();
- }
复制代码 线程间通信多个线程操作同一个资源,但是操作动作不同
input---资源---output wait(),notify(),notifyAll()为何定义在Object类中
线程运行时内存会建立线程池,等待的线程存储在线程池。notify唤醒线程池中线程。
r.wait() //锁对象调用wait,使持有该锁的线程等待。
wait(),notify,notifyAll都使用在同步中,因为对持有监视器(锁)的线程操作。
所以要使用在同步中,因为只有同步才有锁。
这些方法在操作同步中线程时,都必须要标识他们所操作线程持有锁,只有同一个锁上的被等待线程,可以被同一个锁上notify唤醒,不可以对不同锁中的线程进行唤醒。也就是说,等待唤醒必须是同一个锁。而锁可以是任意对象,所以可以被任意对象调用方法定义在object中。 - public class Res {
- private String name;
- private String sex;
- private boolean flag=false;
- public synchronized void set(String name,String sex){
- if(flag)
- try{this.wait();}catch(Exception e){e.printStackTrace();}
- this.name=name;
- this.sex=sex;
- flag=true;
- this.notify();
- }
- public synchronized void out(){
- if(!flag)
- try{this.wait();}catch(Exception e){e.printStackTrace();}
- System.out.println(name+"----"+sex);
- flag=false;
- this.notify();
- }
- public static void main(String[] args) {
- Res r=new Res();
- Input in= new Input(r);
- Output out=new Output(r);
- Thread t1=new Thread(in);
- Thread t2=new Thread(out);
- t1.start();
- t2.start();
- }
- }
- class Input implements Runnable{
- private Res r;
- public Input(Res r) {
- this.r=r;
- }
- @Override
- public void run() {
- int x=0;
- while(true){
- if(x==0){
- r.set("John", "man");
- }else{
- r.set("lili", "woman");
- }
- x=(x+1)%2;
- }
- }
- }
- class Output implements Runnable{
- private Res r;
- public Output(Res r) {
- this.r=r;
- }
- @Override
- public void run() {
- while(true){
- r.out();
- }
- }
- }
复制代码 毕向东老师视频知识点笔记---多线程(2)
|