1、创建多线程方式1——继承Thread类。
   步骤:
       A:自定义类MyThread继承Thread类。
       B:MyThread类里面重写run()?
          为什么是run()方法呢?
       C:创建对象
       D:启动线程

/* 方式1:继承Thread类。
* 步骤
* A:自定义类MyThread继承Thread类。
* B:MyThread类里面重写run()?
* 为什么是run()方法呢?
* C:创建对象
* D:启动线程
*/
public class MyThread extends Thread {//继承Thread类 /* 该类要重写run()方法,为什么呢?
* 不是类中的所有代码都需要被线程执行的。
* 而这个时候,为了区分哪些代码能够被线程执行,java提供了Thread类中的run()用来 包含那些被线程执行的代码。
*/ @Override
public void run() {
// 自己写代码
// System.out.println("好好学习,天天向上");
// 一般来说,被线程执行的代码肯定是比较耗时的。所以我们用循环改进
for (int x = 0; x < 200; x++) {
System.out.println(x);
}
} }
public class MyThreadDemo {
public static void main(String[] args) {
// 创建线程对象
// MyThread my = new MyThread();
// // 启动线程
// my.run();
// my.run();
// 调用run()方法为什么是单线程的呢?
// 因为run()方法直接调用其实就相当于普通的方法调用,所以你看到的是单线程的效果
// 要想看到多线程的效果,就必须说说另一个方法:start()
// 面试题:run()和start()的区别?
// run():仅仅是封装被线程执行的代码,直接调用是普通方法
// start():首先启动了线程,然后再由jvm去调用该线程的run()方法。
// MyThread my = new MyThread();
// my.start();
// // IllegalThreadStateException:非法的线程状态异常
// // 为什么呢?因为这个相当于是my线程被调用了两次。而不是两个线程启动。
// my.start(); // 创建两个线程对象
MyThread my1 = new MyThread();
MyThread my2 = new MyThread(); my1.start();
my2.start();
}
}

2、线程对象调用 run方法和调用start方法区别?

线程对象调用run方法不开启线程。仅是对象调用方法。线程对象调用start开启线程,并让jvm调用run方法在开启的线程中执行。

3、为什么要重写run()方法?(和代码中注释的一个意思)

自定义线程需要执行的任务都定义在run方法中。Thread类中的run方法内部的任务并不是我们所需要,只有重写这个run方法,既然Thread类已经定义了线程任务的位置,只要在位置中定义任务代码即可。所以进行了重写run方法动作。

4、获取线程名称

public class MyThread extends Thread {//继承Thread内

    public MyThread() {
} public MyThread(String name){
super(name);
}
//重写run()方法
@Override
public void run() {
for (int x = 0; x < 100; x++) {
System.out.println(getName() + ":" + x);
}
}
}
/*
* 如何获取线程对象的名称呢?
* public final String getName():获取线程的名称。
* 如何设置线程对象的名称呢?
* public final void setName(String name):设置线程的名称
*
* 针对不是Thread类的子类中如何获取线程对象名称呢?
* public static Thread currentThread():返回当前正在执行的线程对象
* Thread.currentThread().getName()
*/
public class MyThreadDemo {
public static void main(String[] args) {
// 创建线程对象
//无参构造+setXxx()
// MyThread my1 = new MyThread();
// MyThread my2 = new MyThread();
// //调用方法设置名称
// my1.setName("线程1");
// my2.setName("线程2");
// my1.start();
// my2.start(); //带参构造方法给线程起名字
// MyThread my1 = new MyThread("线程1");
// MyThread my2 = new MyThread("线程2");
// my1.start();
// my2.start(); //我要获取main方法所在的线程对象的名称,该怎么办呢?
//遇到这种情况,Thread类提供了一个很好玩的方法:
//public static Thread currentThread():返回当前正在执行的线程对象
System.out.println(Thread.currentThread().getName());
}
}

5、创建多线程的方法2——实现Runnable接口

  步骤:
       A:自定义类MyRunnable实现Runnable接口
       B:重写接口中的run()方法
       C:创建MyRunnable类的对象
       D:创建Thread类的对象,并把C步骤的对象作为构造参数传递

/*
* 方式2:实现Runnable接口
* 步骤:
* A:自定义类MyRunnable实现Runnable接口
* B:重写run()方法
* C:创建MyRunnable类的对象
* D:创建Thread类的对象,并把C步骤的对象作为构造参数传递
*/ public class MyRunnable implements Runnable {//步骤一:自定义类实现Runnable接口 @Override
public void run() {//重写run()方法
for (int x = 0; x < 100; x++) {
// 由于实现接口的方式就不能直接使用Thread类的方法了,但是可以间接的使用
System.out.println(Thread.currentThread().getName() + ":" + x);
}
} public class MyRunnableDemo {
public static void main(String[] args) {
// 创建MyRunnable类的对象
MyRunnable my = new MyRunnable(); // 创建Thread类的对象,并把C步骤的对象作为构造参数传递
// Thread(Runnable target)
// Thread t1 = new Thread(my);
// Thread t2 = new Thread(my);
// t1.setName("线程1");
// t2.setName("线程2"); // Thread(Runnable target, String name)
Thread t1 = new Thread(my, "线程1");
Thread t2 = new Thread(my, "线程2"); t1.start();
t2.start();
}
}

6、实现Runnable的原理

  为什么需要定一个类去实现Runnable接口呢?继承Thread类和实现Runnable接口有啥区别呢?

实现Runnable接口,避免了继承Thread类的单继承局限性。覆盖Runnable接口中的run方法,将线程任务代码定义到run方法中。创建Thread类的对象,只有创建Thread类的对象才可以创建线程。线程任务已被封装到Runnable接口的run方法中,而这个run方法所属于Runnable接口的子类对象,所以将这个子类对象作为参数传递给Thread的构造函数,这样,线程对象创建时就可以明确要运行的线程的任务。

7、实现Runnable的好处

  第二种方式实现Runnable接口避免了单继承的局限性,所以较为常用。实现Runnable接口的方式,更加的符合面向对象,线程分为两部分,一部分线程对象,一部分线程任务。继承Thread类,线程对象和线程任务耦合在一起。一旦创建Thread类的子类对象,既是线程对象,有又有线程任务。实现runnable接口,将线程任务单独分离出来封装成对象,类型就是Runnable接口类型。Runnable接口对线程对象和线程任务进行解耦。

java学习笔记 --- 多线程(多线程的创建方式)的更多相关文章

  1. 【原】Java学习笔记032 - 多线程

    package cn.temptation; public class Sample01 { public static void main(String[] args) { /* * [进程]:正在 ...

  2. java学习笔记(5)多线程

    一.简介(过段时间再写,多线程难度有点大) --------------------------------------- 1.进程:运行时的概念,运行的应用程序 2.线程:应用程序内部并发执行的代码 ...

  3. Java 学习笔记(11)——多线程

    Java内部提供了针对多线程的支持,线程是CPU执行的最小单位,在多核CPU中使用多线程,能够做到多个任务并行执行,提高效率. 使用多线程的方法 创建Thread类的子类,并重写run方法,在需要启动 ...

  4. Java学习笔记之——多线程

    多线程编程 程序: 进程:一个程序运行就会产生一个进程 线程:进程的执行流程,一个进程至少有一个线程,称为主线程 如:QQ聊着天,同时在听音乐 一个进程可以有多个线程,多个线程共享同一个进程的资源 线 ...

  5. Java学习笔记:多线程(一)

    Java中线程的五种状态: 新建状态(New) 就绪状态(Runnable) 运行状态(Running) 阻塞状态(Blocked) 凋亡状态(Dead) 其中阻塞状态(Blocked)又分为三种: ...

  6. Java学习笔记:多线程(二)

    与线程生命周期相关的方法: sleep 调用sleep方法会进入计时等待状态,等待时间到了,进入就绪状态. yield 调用yield方法会让别的线程执行,但是不确保真正让出.较少使用,官方注释都说 ...

  7. JAVA学习笔记16——线程的创建和启动

    Java使用Thread类代表线程,所有的线程对象都必须是Thread类或其子类的实例.每个线程的作用是完成一定的任务,实际上就是执行一段程序流(一段顺序执行的代码).Java使用线程执行体来代表这段 ...

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

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

  9. 0037 Java学习笔记-多线程-同步代码块、同步方法、同步锁

    什么是同步 在上一篇0036 Java学习笔记-多线程-创建线程的三种方式示例代码中,实现Runnable创建多条线程,输出中的结果中会有错误,比如一张票卖了两次,有的票没卖的情况,因为线程对象被多条 ...

  10. Java:多线程概述与创建方式

    目录 Java:多线程概述与创建方式 进程和线程 并发与并行 多线程的优势 线程的创建和启动 继承Thread类 start()和run() 实现Runnable接口 实现Callable接口 创建方 ...

随机推荐

  1. SAP后勤模块实施攻略——1.ERP和SAP

    近日接到任务,看完乐立骏老师的SAP后勤模块实施攻略这本书,现在把第一章内容简单整理.第一章讲的是关于ERP和SAP的介绍. 1.ERP E:Enterprise / 企业 R:Resource / ...

  2. ubuntu16.04的下载地址

    官网不推荐 https://www.ubuntu.com/download 阿里云开源镜像站 http://mirrors.aliyun.com/ubuntu-releases/16.04/ 浙江大学 ...

  3. Oracle11g用户频繁锁定并且解锁后不允许登录

    原因有可能是oracle的密码过期机制导致的:一.由于Oracle中默认在default概要文件中设置了“PASSWORD_LIFE_TIME=180天”所导致.解决办法:1.查看用户用的哪种prof ...

  4. CSS素材+特效

    1.字体:https://www.zhihu.com/question/19680724 2.loading特效:http://www.cnblogs.com/lhb25/archive/2013/1 ...

  5. loadrunder之脚本篇——int类型和字符串的相互转换

    字符串转化为int型变量 Action2() { int j = 0; j = atoi("12345");  //将字符串变为整形 lr_output_message(" ...

  6. Swift中字典解析后的问题,!?两种拆包的差别

    给出一个json,使用SwiftyJSON解析传给model,传进去是个字典,字典里有String,NSNumber,NSDoctionary,和NSArray. 正常情况下直接使用下面的解析方法即可 ...

  7. SpringBoot整合Redis集群

    一.环境搭建 Redis集群环境搭建:https://www.cnblogs.com/zwcry/p/9174233.html 二.Spring整合Redis集群 1.pom.xml <proj ...

  8. Linux基本命令 帮助命令

    命令名称:man 英文原意:manual 命令所在路径:/usr/bin/man 执行权限:所有用户 语法:man [命令或者配置文件] 功能描述:获取帮助信息 例如:man ls 查看ls命令的帮助 ...

  9. 【leetcode刷题笔记】Insert Interval

    Given a set of non-overlapping intervals, insert a new interval into the intervals (merge if necessa ...

  10. Windos Server 2008 Backup 安装使用

    系统环境:Windos 2008 R2 x64 实施方案:备份系统 完全备份,每周备份一次,备份文件映射到文件服务器. 安装备份工具 使用Windos Sserver Backup 做备份 设置每周备 ...