多线程笔记

【掌握的】

1.两种方式创建线程:(继承,实现)

2.继承和实现的区分

3.线程的生命周期 

4.不同状态下,所对应的方法。【通过哪些方法,可以让线程达到某个状态。】

5.同步代码块,同步方法。

----------------------

1.学习多线程的原因?

  生活中:

   程序:  一个完整的功能代码。(方法,没有被运行)

   进程:  一个完整的功能代码。(方法,被运行)

   线程:  进程包含线程。


  好处:提高代码的执行效率。总是有一些功能是需要同时执行的,那就需要多线程。


2.主线程:
 
   -----执行main方法里的代码。

  普通线程
   ------run 方法里的代码。


3.完成线程的步骤:


   A. 编写线程类:(1.通过继承)

   B. 重写run方法:

   C. 创建线程对象,调用start方法,开启线程。


  补充:

   (1) 线程对象.run();  没有开启线程,只是在调用线程对象的run()方法。                  
         线程对象.start(); 线程开启的标志,自动调用run()方法
   
   (2) 调用start()方法就立刻执行run()方法吗?


        线程对象.start(); ----当前线程所处的状态是“就绪状态”

             真正执行run();----当前线程所处的状态是“运行状态”

        ----“就绪状态” 和“运行状态” 之间,间隔多久,不清楚。
 

   (3)线程  【默认命】和【指定名】。


        普通线程的默认名:Thread-变量    ----变量static的,从0开始计数

            主线程默认名:main


        
         // private String name;   //1.接收外界传入的参数,完成线程名。
  // public Thread1(String name){
  //   this.name=name;
  // }
 
   public Thread1(String name){//2.调用父类有参,完成线程命名。
    super(name);
   }

 public void run() {
     // Thread.currentThread().setName(name);
  for (int i = 1; i <= 10; i++) {
   System.out.println
   (Thread.currentThread().getName()+"--->"+i);
  }
 }


  【2.通过实现完成线程】
    
   A.编写线程类:


   B.。重写run()方法


   C。创建线程实现类对象,

       创建线程对象,

       线程对象调用方法,开启线程。

      
   补充: (1.) Thread 实现 Runnable接口
 
          (2.)Thread  th

                Thread2  th2
          都实现Runnable接口 ,在th .start();---th2.run()被执行。【代理模式】
    

          (3.)继承方式, VS 实现方式  哪种线程类更好?

                 实现方式 好:

                 1.可以多实现

                 2.数据共享。

                【例子:3个窗口同时销售5张火车票】
               
            
                【继承方式:】
public class ThreadPiao extends Thread {
        private int piao=5;
 
 public void run() {
  
    for(int i=1;i<=100;i++){
     if(piao>0){
      System.out.println
      (Thread.currentThread().getName()+"---"+piao--);
     }
    }
 
 }
}
 
      【测试代码】
                new ThreadPiao().start();
  new ThreadPiao().start();
  new ThreadPiao().start();

              【实现方式】
public class ThreadP implements Runnable {

 private int piao=5;
 
 public void run() {
   for(int i=1;i<=100;i++){
      if(piao>0){
       System.out.println
       (Thread.currentThread().getName()+"---"+piao--);
      }
     }
 }

}
          【测试代码】
                ThreadP tp=new ThreadP();
  new Thread(tp).start();
  new Thread(tp).start();
  new Thread(tp).start(); 


    问题:继承方式,可不可以只new 1个线程对象,然后调用3次start()方法?

       

4.线程状态/生命周期:
   A.新生状态:   new 线程类();
   B.就绪状态:   start();  【有被执行的资格,但是还没有被cpu调度;队列】
   C.运行状态:   run();   
   D.阻塞状态:  sleep():  礼让 yi  ();  强制 join();
   D.死亡状态:A。正常线程结束 B。发生异常,产生异常对象,没有被截获。

              C。线程自身调用了Stop()。---不被使用


 4.1新生状态:
  
     创建线程对象,可以调用无参,有参(给线程命名)
     ---可以获得到的信息:

       1.获得线程对象。名字 Thread.currentThread().getName()

       2.设置或获得当前线程的优先级:
         th.setPriority(9);
  System.out.println("线程优先级最大是:"+Thread.MAX_PRIORITY);
  System.out.println("线程优先级最大是:"+Thread.MIN_PRIORITY);
  System.out.println("th1的线程优先级是:"+th.getPriority());
  
   4.2就绪状态:

        是否处于就绪状态:Thread.currentThread().isAlive()
        
   4.3运行状态:

     程序执行run();【有被执行的资格,同时也被CPU调度。但是至于什么时间被执行的,不清楚】


  4.4阻塞状态:

      【线程强制执行:join()】

      for (int i = 1; i <=10; i++) {
   if(i==3){
    try {
     th.join();
    } catch (InterruptedException e) {
     e.printStackTrace();
    }
   }
         System.out.println(Thread.currentThread().getName()+"--"+i);
  }
         说明:普通线程强制抢占了cpu资源。

               主线程:由原来的运行状态----》阻塞状态---就绪状态---运行状态

               普通线程:直接运行结束。

         使用场合:线程有明确的【完成先后顺序】。  
   

      【线程休眠:sleep()】

           for (int i = 1; i <=10; i++) {
   if(i==3){
     Thread.sleep(3000);//单位是毫秒
   }
         System.out.println(Thread.currentThread().getName()+"--"+i);
    }

        说明:(1)当前线程休眠:由原来的运行状态----》阻塞状态---就绪状态---运行状态
                   ---休眠时间结束,进入到就绪状态,等待cpu调度。

              (2)中途阻止休眠:(了解)    
                   【例子:】
                   终止休眠: 1. th.interrupt();
                             2.  在异常捕获的时候,出现return。


      【线程礼让:】

            for (int i = 0; i < 10; i++) {
   if(i==3){
    Thread.yield();
    System.out.println("线程礼让一次");
   }
   System.out.println(i);
  }
             说明:让出当前这次cpu资源:线程状态不阻塞---直接进行就绪状态--运行状态。


5.线程安全:

      多线程同时操作数据资源,会出现数据不正确。所需线程同步。
  

    第一种方式:同步代码块  ---使用在线程中。

 public void run() {
   
 for (int i = 1; i <=100; i++) {
  synchronized(this){
   if(piao>0){
    try {
     Thread.sleep(1000);
    } catch (InterruptedException e) {
     e.printStackTrace();
    }
 System.out.println(Thread.currentThread().getName()+"--"+piao--);
   }
  }
 }
  
 }

    第二种方式:同步方法:
         
 public void run() {
   
    for (int i = 1; i <=100; i++) {
  
    maip();
  
   }
  
 }

     public synchronized void maip(){
  if(piao>0){
   try {
    Thread.sleep(1000);
   } catch (InterruptedException e) {
    e.printStackTrace();
   }
 System.out.println(Thread.currentThread().getName()+"--"+piao--);
  }
 }

原文地址:https://www.cnblogs.com/zhuhuibiao/p/9313876.html