• 18.2 实现线程的两种方式


    一、概述
      在Java中主要提供两种方式实现线程,分别为继承java.lang.Thread类与实现java.lang.Runnable接口。

    二、继承Thread类
      a、Thread类是java.lang包中的一个类,从这个类中实例化的对象代表线程,程序员启动一个新线程需要建立Thread类实例。
      Thread类中常用的两个构造方法如下:
        public Thread():创建一个新的线程对象。
        public Thread(String threadName):创建一个名称为threadName的线程对象。
      b、完成线程真正功能的代码放在类的run()方法中,当一个类继承Thread类后,就可以在该类中覆盖run()方法,将实现该线程功能的代码写入run()方法中,然后同时调用Thread类中的start()方法执行线程,也就是调用run()方法。
      c、Thread对象需要一个任务来执行,任务是指线程在启动时执行的工作,该工作的功能代码被卸载run()方法总。
      run()方法必须使用以下语法格式:
        public void run(){
        }
      d、当执行一个线程程序时,就自动产生一个线程,主方法正式在这个线程上运行的。当不在启动其它线程是,该程序就是单线程程序,如在本章已签的程序都是单线程程序。主方法线程启动有java虚拟机负责,程序员负责启动自己的线程。
      代码如下:
        public static void main(String[] args){
          new ThreadTest().start();
        }
    注意:(1)、如果start()方法调用一个已经启动的线程,系统将抛出IllegalThreadStateException异常。
          (2)、在main方法中,使线程执行需要调用Thread类中的start()方法,strat()方法调用被覆盖的run()方法,如果不调用start()方法,线程永远都不会启动,在主方法没有调用start()方法之前,Thread对象只是一个实例,而不是一个真正的线程。

     1 package com.lzw;
     2 
     3 public class ThreadTest extends Thread {    //指定继承Thread类
     4     private int count = 10;
     5     public void run() {        //重写run()方法
     6         while(true) {
     7             System.out.print(count + "  ");
     8             if (--count == 0) {
     9                 return;
    10             }
    11         }
    12     }
    13     public static void main(String[] args) {
    14         new ThreadTest().start();    
    15     }
    16 }
    View Code

    三、实现Runnable接口

      有兴趣的读者可以查询API,从中可以发现,实质上Thread类实现了Runnable接口,其中的run()方法正式对Runnalble接口中的run()方法的具体实现。
      a、实现Runnable接口的程序会创建一个Thread对象,并将Runnable对象与Thread对象相关联。
      Thread对象有以下两个构造方法:
        public Thread(Runnable target)
        public Thread(Runnable target, String name)
      这两个构造方法的参数中都存在Runnable实例,使用以上构造方法就可以将Runnable实例与Thread实例相关联。
      b、使用Runnable接口启动新的线程步骤如下:
        (1)、建立Runnable对象。
        (2)、使用参数Runnable对象的构造方法创建Thread实例。
        (3)、调用start()方法启动线程。
      c、通过Runnable接口创建线程时程序员首先需要编写一个实现Runnable接口的类,然后实例化该类的对象这样就建立了Runnable对象;接下来使用相应的构造方法创建Thread实例;最后使用该实例调用Thread类中的start()方法启动线程。线程最引人注目的部分应该是与Swing相结合创建GUI程序,下面演示一个GUI程序,该程序实现了图标滚动的功能。

     1 package com.lzw;
     2 
     3 import java.awt.*;
     4 import java.net.*;
     5 
     6 import javax.swing.*;
     7 
     8 public class SwingAndThread extends JFrame {
     9     /**
    10      * 
    11      */
    12     private static final long serialVersionUID = 1L;
    13     private JLabel jl = new JLabel(); // 声明JLabel对象
    14     private static Thread t; // 声明线程对象
    15     private int count = 0; // 声明计数变量
    16     private Container container = getContentPane(); // 声明容器
    17     
    18     public SwingAndThread() {
    19         setBounds(300, 200, 250, 100); // 绝对定位窗体大小与位置
    20         container.setLayout(null); // 使窗体不使用任何布局管理器
    21         URL url = SwingAndThread.class.getResource("/1.gif"); // 获取图片的URL
    22         System.out.println(url);
    23         Icon icon = new ImageIcon(url); // 实例化一个Icon
    24         jl.setIcon(icon); // 将图标放置在标签中
    25          // 设置图片在标签的最左方
    26         jl.setHorizontalAlignment(SwingConstants.LEFT);
    27         jl.setBounds(10, 10, 200, 50); // 设置标签的位置与大小
    28         jl.setOpaque(true);
    29         t = new Thread(new Runnable() { // 定义匿名内部类,该类实现Runnable接口
    30                     public void run() { // 重写run()方法
    31                         while (count <= 200) { // 设置循环条件
    32                              // 将标签的横坐标用变量表示
    33                             jl.setBounds(count, 10, 200, 50);
    34                             try {
    35                                 Thread.sleep(1000); // 使线程休眠1000毫秒
    36                             } catch (Exception e) {
    37                                 e.printStackTrace();
    38                             }
    39                             count += 4; // 使横坐标每次增加4
    40                             if (count == 200) {
    41                                 // 当图标到达标签的最右边,使其回到标签最左边
    42                                 count = 10;
    43                             }
    44                         }
    45                     }
    46                 });
    47         t.start(); // 启动线程
    48         container.add(jl); // 将标签添加到容器中
    49         setVisible(true); // 使窗体可视
    50         // 设置窗体的关闭方式
    51         setDefaultCloseOperation(WindowConstants.DISPOSE_ON_CLOSE);
    52     }
    53     
    54     public static void main(String[] args) {
    55         new SwingAndThread(); // 实例化一个SwingAndThread对象
    56     }
    57 }
    View Code

     

  • 相关阅读:
    bzoj3237 cdq分治+可撤销并查集
    bzoj2957 奥妙重重的线段树
    bzoj3718 树状数组
    bzoj3991 LCA + set
    codeforces794D dfs+图上hash
    [ZJOI2010]数字计数/烦人的数学作业
    [SCOI2009]windy数
    数位DP(学习笔记)
    UVA10559 方块消除 Blocks
    采蘑菇
  • 原文地址:https://www.cnblogs.com/studycode/p/9573245.html
Copyright © 2020-2023  润新知