• Java学习笔记-多线程-创建线程的方式


    创建线程

    • 创建线程的方式:
      • 继承java.lang.Thread
      • 实现java.lang.Runnable接口
    • 所有的线程对象都是Thead及其子类的实例
    • 每个线程完成一定的任务,其实就是一段顺序执行的代码

    继承java.lang.Thread创建线程

    public class Test1  { 
        public static void main(String[] args){ 
            System.out.println("现在是主线程: "+Thread.currentThread());
            //用静态方法获取当前正在执行的线程
            System.out.println("下面新建两个线程");
            new Test(100).start();
            new Test(100).start();                                      
          //这里开启两个线程,但不是完成同一件任务
        }
    }
    class Test extends Thread{                                         
    //继承Thread类 private int tickets; Test (int tick){ tickets=tick; } public void run(){ for (;tickets>0;tickets--) { System.out.println("当前线程:"+getName()+" 卖出第 "+tickets+" 张票。"); //用this获得当前线程 if (tickets==1){ System.out.println("票已卖完,当前线程是: "+getName()); } } } }

    0036 Java学习笔记-多线程-创建线程的三种方式

     

    创建线程

    • 创建线程的三种方式:
      • 继承java.lang.Thread
      • 实现java.lang.Runnable接口
      • 实现java.util.concurrent.Callable接口
    • 所有的线程对象都是Thead及其子类的实例
    • 每个线程完成一定的任务,其实就是一段顺序执行的代码

    继承java.lang.Thread创建线程

    package testpack;
    
    public class Test1  { 
        public static void main(String[] args){ 
            System.out.println("现在是主线程: "+Thread.currentThread());  //用静态方法获取当前正在执行的线程
            System.out.println("下面新建两个线程");
            new A(100).start();
            new A(100).start();                                       //这里开启两个线程,但不是完成同一件任务
        }
    }
    class A extends Thread{                                           //继承Thread类
        private int tickets;
        A (int tick){
            tickets=tick;
        }
        public void run(){
            for (;tickets>0;tickets--) {
                System.out.println("当前线程:"+getName()+" 卖出第 "+tickets+" 张票。");  //用this获得当前线程
                if (tickets==1){
                    System.out.println("票已卖完,当前线程是: "+getName());
                }
            }
        }
    }
    • 继承Thread类,开启线程的步骤:
      • 定义一个类,继承Thread,重写run()方法,run()方法就是线程要完成的任务
      • 创建该类的实例,并调用start()方法启动线程
    • 继承Thread类开启的线程,各自完成各自的任务

    实现java.lang.Runnable接口创建线程

    public class Test1  { 
        public static void main(String[] args){ 
            System.out.println("现在是主线程: "+Thread.currentThread()); 
            System.out.println("下面新建两个线程");
            Test test=new Test(100);                                
       //创建一个任务的对象
            new Thread(test,"线程A").start();                   
     //以同一个任务对象为target,开启两个线程
            new Thread(test,"线程B").start();                   
     //两个线程完成同一项任务,但是二者协作沟通不好
        }
    }
    class Test implements Runnable{                             
      //实现Runnable接口
        private int tickets;
        Test (int tick){
            tickets=tick;
        }
        public void run(){                                 
        //同样重写run()方法,就是线程要完成的任务
            for (;tickets>0;tickets--) {
                System.out.println("当前线程:"+Thread.currentThread()+" 卖出第 "+tickets+" 张票。");
                if (tickets==1){
                    System.out.println("票已卖完,当前线程是: "+Thread.currentThread());
                }
            }
        }
    }
    
    • 实现Runnable接口开启线程的步骤:
      • 定义一个类,实现Runnbale接口,重写run()方法
      • 创建该类的对象,即任务对象
      • 以任务对象为target,创建线程,调用start()方法
    • 通过Runnable接口创建的多个线程,可以写作完成同一件任务,只是协作方面有待改进

    Thread、Runnable的比较

    • Thread:
      • 不能继承其他类;
      • 用this获取当前线程
      • 多个线程不能执行同一个target任务
    • Runnable:
      • 可以继承其他类;
      • 用Thread.currentThread()获取当前线程
      • 多个线程可以执行同一个target任务

    线程的生命周期

    • 新建(New):
      • 创建线程对象后,就处于“新建”状态,此时跟一个普通的对象无异
      • 只能对新建状态的线程对象,调用start()方法
    • 就绪(Runnable):
      • 调用start()方法后,处于就绪状态,虚拟机为其创建方法调用栈和程序计数器
      • 何时开始运行,取决于JVM的调度
      • 就绪状态可能从“新建”、“阻塞”、“运行”三种状态变化而来
    • 运行(Running):
      • 线程获得了在CPU上运行的权利,开始运行
      • 何时中断执行,也取决于调度,一个线程不可能一直占着cpu
      • 一个线程,可以调用sleep()或者yield()方法,来主动放弃执行权利
    • 阻塞(Blocked):
      • 调用sleep()方法
      • 调用了一个阻塞式的IO方法,该方法返回之前,被阻塞
      • 试图获得一个同步监视器,但该监视器被其他线程所持有
      • 等待其他线程的notify()通知
      • 调用suspend()方法将该线程挂起。尽量避免该种方法,可能导致死锁
    • 死亡(dead):
      • 线程任务执行完成
      • 线程抛出未捕获的异常或错误
      • 调用线程的stop()方法
      • 主线程运行结束,不影响子线程的继续运行
      • boolean isAlive()方法返回线程是否已死亡:处于新建和死亡两种状态返回false,其他三种状态返回true

    start()与run()方法

      • 永远不要调用线程对象的run()方法。直接调用run()方法的话,那么就只是一个普通方法,而不是线程任务
      • 调用了run()方法之后,会改变线程对象的状态,不再是新建状态,因而也就不能调用start()方法
      • 只能对处于新建状态的线程对象调用start()方法,且只能调用一次,否则抛出IllegalThreadStateException异常
  • 相关阅读:
    HDU 3757 Evacuation Plan DP
    UVa 1473
    LA 6047 Perfect Matching 字符串哈希
    HDU 3038 How Many Answers Are Wrong 并查集带权路径压缩
    专业程序员必知必会技巧:驯服复杂代码
    OpenCV、OpenCL、OpenGL、OpenPCL
    关于dlg和pro的问题
    关于编译PCL1.71
    VS2010编译错误:fatal error C1189: #error : This file requires _WIN32_WINNT to be #defined at least to 0x
    AI:从游戏引擎--到AI
  • 原文地址:https://www.cnblogs.com/houjiie/p/6181917.html
Copyright © 2020-2023  润新知