前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >juc07 创建线程

juc07 创建线程

作者头像
潇洒
发布2023-10-20 10:11:26
1320
发布2023-10-20 10:11:26
举报
文章被收录于专栏:石头岛

创建线程

JAVA中线程被封装成Thread对象。JDK API中有对Thread的说明,连创建方式都有。 自定义线程有两种方式:

  1. 继承Thread
  2. 实现Runable接口

从打印结果是否是不同线程运行来验证多线程执行。 主线程代码在main方法中,自定义线程方法代码在run方法中。

两种创建方式的区别:

  1. Thread 的代码是存在子类当中;
  2. Runable方式的代码是的实现接口的子类当中,还避免了单继承的问题。

一、继承 Thread 方式

这种方式最简单,需要三个步骤:

  1. 继承 Thread 类
  2. 重写 run 方法,run方法要看成一个入口点。
  3. 调用 start 方法来执行自定义线程

实现代码:

代码语言:javascript
复制
public class TestThread extends Thread {
  //1.继承Thread
  @Override
  public void run() {

    //2.重写run方法
    //super.run();
    for (int i = 0; i < 100; i++) {
      System.out.println("run: "+ i);
    }
  }

  public static void main(String[] args) {
    //3.执行start线程
    TestThread testThread = new TestThread();
    testThread.start();
    for (int i = 0; i < 100; i++) {
      System.out.println("main: "+ i);
    }
  }
}

结果 会交替打印 run 和 main 证明CPU执行线程时是交替进行的。而且这种交替是随机性的。

说明:run方法中写上自定义线程要执行的程序,而调用 start 才是真正表示开始执行这条自定义线程。 理解: main是程序默认线程入口,run 是自定义程序入口,和 main 等价。 但是 main 是程序开启的,run 是由用户开启的。

注意事项

  1. 注意this

如果继承自Thread类,可以直接使用this关键字来调用Thread类中的方法,如getName方法,因为是继承所以可以直接使用方法。

  1. 注意super

继承Thread后,也可以直接调用父类的方法给自己用,而不需要.currentThread.方法。 如super(name); 直接调用构造方法重命名线程。

二、Runable 方式

这种方式业务类必须实现Runnable接口,并将业务类所创建的对象传入 Thread 对角中去。 由于对象只有一份,所以多个 Thread 对象操作的是同一个对象,所以就会产生共享数据的问题,即,不安全问题的产生。

代码实现

代码语言:javascript
复制
public class TestSun {
  public static void main(String[] args) {
    TestClass c = new TestClass();
    TestClass d = new TestClass();

    Thread t1 = new Thread(c);        //TestClass 必须实现Runnable的run方法才能使用这种方式。
    Thread t2 = new Thread(d);
    t1.start();
    t2.start();
  }
}

// 继承 Runnable
class TestClass implements Runnable {
  public void run() {
    System.out.println("子类重写run方法");
  }
}

多写一个例子:

代码语言:javascript
复制
public class TestSun implements Runnable {
  public static void main(String[] args) {
    TestSun testSun = new TestSun();
    Thread t = new Thread(testSun);
    t.start();
  }

  public void run() {
    //do 
  }
}

理解:例用实现Runnable还有一个好处就是,我不同的类,我可以有不同的run实现方法,

Runable 共享资源问题

下面代码的执行结果是:输出 50次。如果使用继承Thread的方式的话,会被执行200次。 原就是就因为 Test 对象实际上被所有线程所共享,所有线程所操作的时同一个对象。 如果使用Thread方式,给变量i设为静态也可以做到执行50次,但是静态的生命周期太长了,不推荐。 这个例子为了说明 Thread 和 Runable 的区别。 而为什么 Thread 对执行多次,是因为继承的Thread 后,每new 一次,就是创建的一个新对象,每个对象都是一分独立的副本,并不是同一个对象。

代码语言:javascript
复制
package com.liukai.thread;

public class TestThread2 {
  public static void main(String[] args) {
    Test test = new Test();
    Thread t1 = new Thread(test);
    Thread t2 = new Thread(test);
    jhread t3 = new Thread(test);
    t1.start();
    t2.start();
    t3.start();
  }

}

class Test implements Runnable {
  boolean flag = true;
  int i = 50;

  public void run() {
    while (flag) {
      System.out.println(Thread.currentThread().getName() + "---" + i--);
      if (i <= 0) {
        flag = false;
      }
    }

  }

}

区别

runnable 和 继承Thread 方式的区别 这种非常重要的概念,一定要明白。关系到线程的执行方式。

  1. 继承Thread类方式:线程到码存放在Thread子类的run方法中。即继承了Thread类的自定义线程类的run方法中。
  2. 实现Runnable接口方式:线程代码存在接口的子类的run方法中。注意是接口的子类的run方法中,不是实现类的run方法中。

第2种方式最常用。 优点:

  1. 避免单继承的局限性。
  2. 多个业务代码可以有不同的代码存放区。
本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2014-10-25,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 创建线程
  • 一、继承 Thread 方式
    • 注意事项
    • 二、Runable 方式
    • Runable 共享资源问题
    • 区别
    领券
    问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档