zoukankan      html  css  js  c++  java
  • Android(java)学习笔记2:继承Thread类创建线程类

    1. 继承Thread类 创建线程类:

     1 package cn.itcast_02;
     2 
     3 /*
     4  * 该类要重写run()方法,为什么呢?
     5  * 不是类中的所有代码都需要被线程执行的。
     6  * 而这个时候,为了区分哪些代码能够被线程执行,java提供了Thread类中的run()用来包含那些被线程执行的代码。
     7  */
     8 public class MyThread extends Thread {
     9 
    10     @Override
    11     public void run() {
    12         // 自己写代码
    13         // System.out.println("好好学习,天天向上");
    14         // 一般来说,被线程执行的代码肯定是比较耗时的。所以我们用循环改进
    15         for (int x = 0; x < 200; x++) {
    16             System.out.println(x);
    17         }
    18     }
    19 
    20 }


    重写完这个MyThread这个类,我们接下来编写类,添加main方法,创建对象,调用这个类:

     1 package cn.itcast_02;
     2 
     3 /*
     4  * 需求:我们要实现多线程的程序。
     5  * 如何实现呢?
     6  *         由于线程是依赖进程而存在的,所以我们应该先创建一个进程出来。
     7  *         而进程是由系统创建的,所以我们应该去调用系统功能创建一个进程。
     8  *         Java是不能直接调用系统功能的,所以,我们没有办法直接实现多线程程序。
     9  *         但是呢?Java可以去调用C/C++写好的程序来实现多线程程序。
    10  *         由C/C++去调用系统功能创建进程,然后由Java去调用这样的东西,
    11  *         然后提供一些类供我们使用。我们就可以实现多线程程序了。
    12  * 那么Java提供的类是什么呢?
    13  *         Thread
    14  *         通过查看API,我们知道了有2中方式实现多线程程序。
    15  * 
    16  * 方式1:继承Thread类。
    17  * 步骤
    18  *         A:自定义类MyThread继承Thread类。
    19  *         B:MyThread类里面重写run()?
    20  *             为什么是run()方法呢?
    21  *         C:创建对象
    22  *         D:启动线程
    23  */
    24 public class MyThreadDemo {
    25     public static void main(String[] args) {
    26         // 创建线程对象
    27         // MyThread my = new MyThread();
    28         // // 启动线程
    29         // my.run();
    30         // my.run();
    31         // 调用run()方法为什么是单线程的呢?
    32         // 因为run()方法直接调用其实就相当于普通的方法调用,所以你看到的是单线程的效果
    33         // 要想看到多线程的效果,就必须说说另一个方法:start()
    34         // 面试题:run()和start()的区别?
    35         // run():仅仅是封装被线程执行的代码,直接调用是普通方法
    36         // start():首先启动了线程,然后再由jvm去调用该线程的run()方法37         // MyThread my = new MyThread();
    38         // my.start();
    39         // // IllegalThreadStateException:非法的线程状态异常
    40         // // 为什么呢?因为这个相当于是my线程被调用了两次。而不是两个线程启动。第一个已经start已经启动线程,第二个start再启动则会报错。
    41         // my.start();
    42 
    43         // 创建两个不同线程对象
    44         MyThread my1 = new MyThread();
    45         MyThread my2 = new MyThread();
    46 
    47         my1.start();
    48         my2.start();
    49     }
    50 }

    执行代码我们看到了结果如下图:也许有人会问这个第一次运行的0,1,2,3……这样输出的是那个线程的?(my1还是my2线程的?),下面我们会回答这样的问题。

    针对刚刚我们提出的问题,我们来说明一下(我们用代码实现一下):

    这个是我们写的一个线程类:

     1 package cn.itcast_03;
     2 
     3 public class MyThread extends Thread {
     4 
     5     public MyThread() {
     6     }
     7     
     8     public MyThread(String name){
     9         super(name);
    10     }
    11 
    12     @Override
    13     public void run() {
    14         for (int x = 0; x < 100; x++) {
    15             System.out.println(getName() + ":" + x);
    16         }
    17     }
    18 }

    下面我们再次写出测试类:

     1 package cn.itcast_03;
     2 
     3 /*
     4  * 如何获取线程对象的名称呢?
     5  * public final String getName():获取线程的名称。
     6  * 如何设置线程对象的名称呢?
     7  * public final void setName(String name):设置线程的名称
     8  * 
     9  * 针对不是Thread类的子类中如何获取线程对象名称呢?
    10  * public static Thread currentThread():返回当前正在执行的线程对象
    11  * Thread.currentThread().getName()
    12  */
    13 public class MyThreadDemo {
    14     public static void main(String[] args) {
    15         // 创建线程对象
    16         //无参构造+setXxx()
    17         // MyThread my1 = new MyThread();
    18         // MyThread my2 = new MyThread();
    19         // //调用方法设置名称
    20         // my1.setName("林青霞");
    21         // my2.setName("刘意");
    22         // my1.start();
    23         // my2.start();
    24         
    25         //带参构造方法给线程起名字
    26         // MyThread my1 = new MyThread("林青霞");
    27         // MyThread my2 = new MyThread("刘意");
    28         // my1.start();
    29         // my2.start();
    30         
    31         //我要获取main方法所在的线程对象的名称,该怎么办呢?
    32         //遇到这种情况,Thread类提供了一个很好玩的方法:
    33         //public static Thread currentThread():返回当前正在执行的线程对象
    34         System.out.println(Thread.currentThread().getName());
    35     }
    36 }
    37 
    38 /*
    39 名称为什么是:Thread-? 编号,下面是源码(注意这里我只是截取我需要的,方便理解和说明)
    40 
    41 class Thread {
    42     private char name[];
    43 
    44     public Thread() {
    45         init(null, null, "Thread-" + nextThreadNum(), 0);
    46     }
    47     
    48     private void init(ThreadGroup g, Runnable target, String name,
    49                       long stackSize) {
    50         init(g, target, name, stackSize, null);
    51     }
    52     
    53      private void init(ThreadGroup g, Runnable target, String name,
    54                       long stackSize, AccessControlContext acc) {
    55         //大部分代码被省略了
    56         this.name = name.toCharArray();
    57     }
    58     
    59     public final void setName(String name) {
    60         this.name = name.toCharArray();
    61     }
    62     
    63     
    64     private static int threadInitNumber; //0,1,2
    65     private static synchronized int nextThreadNum() {
    66         return threadInitNumber++; //return 0,1
    67     }
    68     
    69     public final String getName() {
    70         return String.valueOf(name);
    71     }
    72 }
    73 
    74 class MyThread extends Thread {
    75     public MyThread() {
    76         super();
    77     }
    78 }
    79 
    80 */

    附上执行效果图:

    这里不得不说这样的线程名字很没有针对性,大家说是不是?当然我们可以自己取线程的名字,调用setName()方法

  • 相关阅读:
    VIM快捷键(转)
    VIM中文乱码
    vsftpd.conf 联机手册
    keepalived nginx 主备配置
    Keepalived 主备配置
    Linux centos7 安装 keepalived-2.0.6
    Linux centos开机执行JAR Shell脚本
    Nginx负载均衡案例
    Windows虚拟机安装Linux系统
    Linux centos7 redis安装教程
  • 原文地址:https://www.cnblogs.com/hebao0514/p/4506859.html
Copyright © 2011-2022 走看看