首页 > 代码库 > java基础_线程

java基础_线程

什么是线程
  >>线程是每一个进程执行的顺序,该顺序是一个执行路径,或者叫做一个控制单元。
      简单来说线程就是一个控制单元或者叫做一个执行路径。
  >>是程序执行流的最小单位
_____________________________________________________________________________________________________________________________________________________________

什么是进程
  >>进程是一个正在执行的程序。
  >>进程是资源分配的基本单位。

__________________________________________________________________________________________________________________________________________________________________

进程和线程的关系
   每个进程至少有一个线程(线程是进程的一个实体,是被系统独立调度和分派的基本单位)
______________________________________________________________________________________________________________________________________________________________________

什么是多线程
   在当个程序中运行多个线程完成不同的工作。
      多线程具有随机性
___________________________________________________________________________________________________________________________________________________________________

生活中的例子
   比如说,政府的行政楼,里面有很多办事窗口,每一个办事窗口相当于一个线程,行政楼相当于进程
   多线程就是相当于行政楼多个窗口
____________________________________________________________________________________________________________________________________________________________________

在代码中定义一个执行线程的步骤
方法(一)
  >>继承Thread类
  >>重新run()方法
  >>调用start()方法
        >>启动线程
        >>调用run()方法
在主函数中调用run方法和调用start方法的区别
  >>直接调用run方法,相当于对象调用方法,这样我们创建了线程,并没有实际上运行了线程,产生的效果就是线执行run,然后在执行主函数(意思就是只有主函数这个线程在执行,我们定义的线程并没有执行)
___________________________________________________________________________________________________________________________________________________________________________________________________

方法(二)
   >>声明实现Runnable接口的类(implements Runnable)
   >> 实现Runnable接口的run方法,
   >>然后可以分配该类的实例
        创建实例对象 比如说买票系统里的Tick t=new Tick()
   >>在创建thread时作为一个参数来传递并启动。
         因为这里的run方法指的是Runnable里的run方法,不是Thread的run方法 
     简单意思就是 Thread t1=new Thread(t) t1.start();


 实现方式(接口)和继承方式区别:
   >>避免了单继承的局限性(定义线程时候,最好采用实现的方式)
   >>实现的方式实现了资源的独立共享
  
对于继承Thread:线程代码存放在Thread子类的run方法中
对于实现,是存放在接口的子类的run方法中 


______________________________________________________________________________________________________________________________________________________________________

线程具有默认的名称
  >>getName();
  >>默认的格式 Thread_编号(0开始)
  >>thread.currentThread==this.getName(); 静态的,获取当前线程对象
  >>setName或者构造函数(Thread(String name){super(name);}) 
_______________________________________________________________________________________________________________________________________________________________________

多线程容易产生安全问题
   >>模拟多线程的安全问题的产生
         >> //try{Thread.sleep(10);}case(Exception e){}
   >>产生问题的原因:
         >>当多条语句在操作同一线程共享数据时,一个线程对多条语句只执行了一部分,还没有执行完,另一个线程参与进来执行,导致共享数据的失误
   >>解决办法:
         >>对多条操作共享数据的语句,只能让一个线程都执行完,在执行过程中,其他线程不能参与执行。
                  >>同步代码块可以解决这个问题
                              >>synchronized(对象){
                                    需要被同步的代码块(那些语句在操作共享数据代码)
                               }
                                >>同步代码块中的对象如锁,持有锁的线程可以在同步中执行
                                  没有持有锁的线程即使获得cpu的执行权,也进不去,因为没有获取锁,
                   >>同步函数也可以解决这个问题
                                >>public synchronized void add(){函数体}

同步的前提:
    >>必须要有两个或者两个以上的线程
    >>必须是多个线程使用同一个锁(即使操纵同一个共享数据)

  好处:
     >>解决了多线程的安全的问题

  弊端:
    >>较为消耗了资源,程序变得比较慢(因为每次都需要判断锁)
  
______________________________________________________________________________________________________________________________________________________   

同步函数是怎么实现锁的功能,有是用什么锁控制多线程的呢?
   >>因为函数被对象调用,那么谁调用这个函数,那么这个锁就是该对象的锁,所以同步函数的锁就是this
             >>可以通过一个写同步代码块,一个用同步函数,来实现判断同步函数是不是this
                      >>如果不出现错误的票,即使使用同一个锁
             >>static synchronized  void show()使用的锁是class字节码对象(Tick.class)
   class Ticket implements Runnable{
        private /*static*/ int tick=100;
        boolean flag=true;
        //为同步代码块提供的对象
        //object obj=new object();
        public void run(){
         while(tick>0){
             //模拟多线程出现安全隐患
             //try{Thread.sleep(10);}case(Exception e){}
             //可以这个解决多线程出现安全隐患
             if (flag){
                       //synchronized(obj)-->synchronized(this)
                      synchronized(this){  
                         try{Thread.sleep(10);}case(Exception e){}         
                                if(tick>0){
                                System.out.println(Thread.currentThread().getName()+" "+"Runnable sale:"+tick--);
                                }
                       } 
              }else{show()}
          }
        }
   }
 
         public synchronized void show{
                 if(tick>0){
                   System.out.println(Thread.currentThread().getName()+" "+"show sale:"+tick--);
                  }
         }

   public class TicketDemo{
        
         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(10);}catch(Exception e){}
            t.flag=flase;
           t2.start();

         }

   }

________________________________________________________________________________________________________________________________________________________

             >>static synchronized  void show()使用的锁是class字节码对象(Tick.class)

   class Ticket implements Runnable{
        private static int tick=100;
        boolean flag=true;
        //为同步代码块提供的对象
        //object obj=new object();
        public void run(){
         while(tick>0){
             //模拟多线程出现安全隐患
             //try{Thread.sleep(10);}case(Exception e){}
             //可以这个解决多线程出现安全隐患
             if (flag){
                       //synchronized(obj)-->synchronized(Tick.class)
                      synchronized(Tick.class){  
                         try{Thread.sleep(10);}case(Exception e){}         
                                if(tick>0){
                                System.out.println(Thread.currentThread().getName()+" "+"Runnable sale:"+tick--);
                                }
                       } 
              }else{show()}
          }
        }
   }
 
         public static synchronized void show{
                 if(tick>0){
                   System.out.println(Thread.currentThread().getName()+" "+"show sale:"+tick--);
                  }
         }

   public class TicketDemo{
        
         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(10);}catch(Exception e){}
            t.flag=flase;
           t2.start();

         }

   }

____________________________________________________________________________________________________________________________________________________

//单例设计
 >>饿汉式
    class single{
          private static void final single sin=new single();
          privaate Single(){}
          public static single getInstance(){
                 return s;
            }
     }

//懒汉式
   class single{
        private static single sin=null;         
        private single(){}                                 
        public static single getInstance(){                     
                if(s==null){s=new single();}                           
                return s;                                                      
        }                                                         
   }                                                                 
//


__________________________________________________________________________________________________________________________________________________________________

//死锁
    >>同步中嵌套同步式出现死锁的原因
       class Test implements Runnable{
            private boolean flag;
            Test(boolean flag){this.flag=flag}
             public void run(){
                   if(falge){
                       synchronized(mylock.locaka){
                           System.out.prinlnt("if locaka");
                           synchronized(mylock.locakb){
                             System.out.prinlnt("if locakb");   
                        }
                   }else{
                       synchronized(mylock.locakb){
                           System.out.prinlnt("else locakb");
                           synchronized(mylock.locaka){
                             System.out.prinlnt("else locaka");   
                        }
                    }
             }
       }

     class mylock{
          static Object locka=new Object();
           static Object locka=new Object();
      }

      public class DeadLockTest{
             public static void main(){
                      Thread t1=new Thread(new Test(true));
                      Thread t2=new Thread(new Test(false));
                      t1.start();
                      t2.start();
              }

       }


____________________________________________________________________________________________________________________________________________

线程间的通信

    >>等待唤醒机制
       >>wait; notify(); notifyAll();都使用在同步中,因为要对持有监视器(锁)的线程操作
           所以要使用在同步中,因为只有同步中这才有具有锁
为什么这些操作线程的方法要定义Object类中呢?
   >>因为这些方法在操作同步线程时,都必须要标识他们所操作线程只有锁
       只有同一个锁上的被等待线程,可以被同一个锁上的notify唤醒
        不可以对不同锁中的线程进行唤醒,也就是说等待和唤醒必须时同一个锁,而锁可以时任意对象,
        所以可以被任意对象调用的方法定义Object类中


jdk升级了多线程解决锁和唤醒机制
   >>lock代替了synchroinzed
   >>condition对像代替了notify和wait以及notifyAll的Object对象


________________________________________________________________________________________________________________

停止线程
  >>如何停止线程能,只有一种方法停止,run结束
     开启多线程运行,通常都是循环结构,只要控制循环,就可以让线程run()结束
//run方法结束停止线程
 //通过控制循环的标签来控制run的结束
//但是有一种情况
   //当线程处于冻结的状态,线程就不会结束,可以用interrupt恢复运行状态,这样在catch里将循环的状态变成flag=false,就可以结束run()[线程]


_____________________________________________________________________________________________________________________________________

守护线程
  >>后台线程(即是守护线程)当所有的前台线程(主线程)结束后,后台线程自动结束
  >>使用守护线程,必须要在开启线程前,使用t1.setDaemon(true);

_________________________________________________________________________________

join加入线程
  >>意思是当使用线程.jion时候,cpu的执行权就会交给申请的线程运行

————————————————————————————————————————
线程的优先级
  >>线程.setPriority(Thread.MAX_PRIORITY);1-10级
  >>Thread.yield :临时暂停,可以达到线程的交替使用


——————————————————————————————————————

线程的应用场景
  >>当某些代码需要同是被执行时,用线程进行封装。
 匿名内部类的写法
   new Thread(){
        public void run(){

        }

   }.start();

java基础_线程