`

黑马程序员——多线程的要点总结

 
阅读更多

        ------- android培训java培训、期待与您交流! ----------

  •  多线程  

简要概述

  1.进程:一个正在执行的程序,每一个进程都有一个执行顺序,该顺序就是一个执行路径或控制单元

  2.线程:进程中的一个控制单元或执行路径,控制着进程的执行

  3.一个进程中至少有一个线程

java vm在启动是会有一个进程java.exe

该进程线中至少有一个线程负责java程序的运行

而且这个线程执行的代码存在于main方法中

该线程称之为主线程

扩展:其实jvm启动不止一个线程,还有负责垃圾回收的一个线程  

 

创建线程的步骤:

 1.创建一个类继承与Thread

 2.重写Thread类中的run方法

   目的:将线程要运行的代码存储在run()方法中

 3.在调用时创建子类的一个实例,调用Thread类的start()方法

    start()有两个作用:1.启动线程      2.调用Thread类中的run()方法

一个进程在执行时,如果有多个线程,系统的cup会无序的将cup时间片分配给单个线程,cpu的转换十分快速,以致我们 看上去多个线程在同时执行

 

发现运行结果每次都不一样

因为多个线程都在抢夺cpu的执行权,谁抢到,谁执行

明确一点,在同一时刻,只能有一个线程执行,(多核除外)

cpu在做着快速的切换,以致达到看上去是在同时执行的效果

我们可以形象的把多线程的运行形容为在互相抢夺cpu的资源

这就是多线程的一个特性:随机性

为什么要覆盖run方法?

Thread类用于描述线程

 该类要定义一个功能,该功能用于存储线程要运行的代码,这些代码就存储在run方法中

 换句话说:run()方法就是用来存储我们自定义线程中要运行的代码  

class Demo extends Thread{
    public void run(){
        for(int i=0;i<50;i++)
        {
            System.out.println("demo run"+i);
        }
    }
}
public class ThreadDemo {
    public static void main(String[] args) {
        Demo demo=new Demo();        
             demo.start();
         for(int j=0;j<50;j++)
         {
             System.out.println("hello word"+j);
         }
    }
}

  

 

线程的运行状态(如图)

  

 

总结

1.线程对象

    调用start()进入线程运行状态

    直接进入就绪状态(具备CPU执行权)

2.运行着的线程

   调用stop(),进入线程销毁状态

   调用wait()进入冻结状态,通过notify()返回运行状态或进入就绪状态

   调用sleep(time)进入冻结状态,sleep时间到返回运行状态或进入就绪状态



 

  • 获取父类对象和名称

Thread也有自己的默认名字:以“Thread-”开头

 第一个名称是Thread-0,

 第二个名称:Thread-1

 以此类推  通过getName()获取

 子类构造函数通过调用父类构造函数super(name)可自定义名称

 

 

实现线程的第二种方式:实现runnable接口

步骤:

1.创建一个实现了runnable接口的类

2.重写runnable接口中的run()方法

    目的:将线程要运行的代码存储在run()方法中

3.创建Thread类(线程)对象

4.将实现了runnable接口的子类对象作为实际参数传递为Thread类的构造函数

       为什么要将实现了runnable接口的子类对象作为实际参数传递为Thread类的构造函数?

        原因:因为线程要运行的代码是封装在runnable接口的子类对象的run()方法中

         所以需要通过该子类对象来指定对应的run()方法

5.调用Thread类的start()方法启动线程,并运行run()方法

 

实现方式和继承方式的区别

 java中不能实现多继承,如果一旦采用继承方式,那么该子类的功能就受到了局限性

     如果一个类需要继承其父类的某些功能,但与此同时,有要求她实现多线程,继承方式显然不顶用

 因此,实现方式的优点就在于:既实现了多线程,又可以通过继承来扩展自己的功能,这就避免了单继承的局限性  

 在定义线程时:建议使用实现方式

 class Demo extends Thread{
    private String name;
    public Demo(String name)
    {
        super(name);//调用父类的构造函数,通过getName()获取自定义线程名称
    }
    public void run(){
        for(int i=0;i<50;i++)
        {
            System.out.println(this.getName()+".......demo run"+i);
        }
    }
class Tickt implements Runnable{
      private int tickts=100;
      public void run(){
          while(tickts>0)
          {
              System.out.println(Thread.currentThread().getName()+"票数:"+tickts--);
          }
      }      
}
public class ThreadDemo {
    public static void main(String[] args) {
        Tickt t=new Tickt();
        Thread thread1=new Thread(t);//实现了runnable接口的子类对象
        Thread thread2=new Thread(t);
        Thread thread3=new Thread(t);
        thread1.start();
        thread2.start();
        thread3.start();
    }
}

 

  • 大小: 43.3 KB
分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics