一、创建线程的三种方式

· 继承Thread类

· 实现Runnable接口

· 实现Callable接口

二、 线程状态

· 线程名字 getName()

· 线程活动情况 isAlive()

· 控制线程运行次序 join()

一、 创建线程的三种方式

① 继承Thread类

/**
* 步骤:
* 继承Thread重写run方法,创建该线程实例,调用start()方法启动线程
* @author ChristineBassoon
*
*/
public class test {
public static void main(String[] args) {
MyThread t = new MyThread();
t.start();
} } class MyThread extends Thread{ @Override
public void run() {
for(int i=0;i<50;i++) {
System.out.println(i+"["+this.getName()+"]");
}
}
}

同种方法以匿名内部类形式

new Thread(){
  @Override
  public void run() {
    for(int i=0;i<50;i++) {
      System.out.println(i+"["+Thread.currentThread().getName()+"]");
    }
  }
}.start();

② 实现Runnable接口

/**
* 步骤:
* 实现Runnable接口,重写run方法,以此Runnable实例作为Thread的target创建Thread对象
* 调用start方法启动线程
* @author ChristineBassoon
*
*/
public class test {
public static void main(String[] args) {
Thread t = new Thread(new MyRunnable());
t.start();
}
} class MyRunnable implements Runnable{ @Override
public void run() {
for(int i=0;i<50;i++) {
System.out.println(i+"["+Thread.currentThread().getName()+"]");
}
}
} //匿名内部类形式
new Thread(new Runnable(){
    @Override
    public void run() {
      for(int i=0;i<50;i++) {
        System.out.println(i+"["+Thread.currentThread().getName()+"]");
      }
    }
  }).start();
}

③ Callable方式

/**
* 步骤:
* 1. 实现Callable接口,使用FutureTask类来包装Callable对象
* 2. FutureTaskd对象作为Thread对象的target创建并启动线程
* (FutureTask同时实现了Runnable和Callable接口,所以能作为Thread对象的的target)
* 3. FutureTask的get()方法在子线程结束后可获得返回值(以此判断线程能否正常运行)
*/
public class test {
public static void main(String[] args) { CallableThread ct = new CallableThread();
FutureTask ft = new FutureTask<>(ct);
new Thread(ft).start();
try {
System.out.println("子线程返回值为:"+ft.get());
} catch (InterruptedException e) {
e.printStackTrace();
} catch (ExecutionException e) {
e.printStackTrace();
}
} } class CallableThread implements Callable { @Override
public Integer call() throws Exception {
for(int i=0;i<50;i++) {
System.out.println(i+"["+Thread.currentThread().getName()+"]");
}
return 1;
}
}

二、线程状态

线程的几个状态可用图概括 (图源自google image),解释得非常清楚

//获取当前线程的名字
Thread.currentThread().getName();
//判断当前线程运行情况
Thread.currentThread().isAlive();
//设定线程的名字
Thread.currentThread().setName("");
//只有该线程结束后,程序才会向下进行
[new Thread()].join();//[]表示某线程

① 获取当前线程名字 —— getName()

情况1,获取主线程名字

public class ThreadTest {
public static void main(String[] args) {
        System.out.println(Thread.currentThread().getName()); }
}

结果为

main

情况2:获取子线程名字

new Thread() {
    @Override
    public void run(){
        for(int i=0;i<5;i++) {
        System.out.println(i+"["+Thread.currentThread().getName()+"]");
        System.out.println(i+"["+this.getName()+"]");
        }
    }
}.start();

结果为

0[Thread-0]
0[Thread-0]
1[Thread-0]
1[Thread-0]
2[Thread-0]
2[Thread-0]
3[Thread-0]
3[Thread-0]
4[Thread-0]
4[Thread-0]

可看出,子程序运行期间,当前的线程( Thread.currentThread() )名字就是子程序的线程名。

②线程运行情况,判断线程是否在运行当中—— isAlive()

public class ThreadTest {
public static void main(String[] args) {
MyThread myThread = new MyThread();
myThread.start();
System.out.println("");
try {
myThread.join();//确保子线程结束后才执行下方语句
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("");
System.out.println("myThread线程运行情况:"+myThread.isAlive());
}
} class MyThread extends Thread { public MyThread(){
System.out.println("====构造函数开始====");
System.out.println(this.isAlive());
System.out.println("====构造函数结束====");
} @Override
public void run(){
System.out.println("=====run开始======");
System.out.println(this.isAlive());
System.out.println("=====run结束======");
}
}

结果为:

====构造函数开始====
false
====构造函数结束==== =====run开始======
true
=====run结束====== myThread线程运行情况:false

总结:子线程只有调用start()方法后才会运行。

③ 线程之间的运行顺序 —— join() 方法的调控

接下来我们实验一下:

public class condition {
public static void main(String[] args) { MyThread myThread = new MyThread();
myThread.setName("子线程");//设定子线程名字
myThread.start();
System.out.println();
System.out.println("主线程运行完毕");
}
} class MyThread extends Thread { @Override
public void run(){
for(int i=0;i<20;i++) {
System.out.println(i+"["+this.getName()+"]");
}
}
}

结果:

主线程运行完毕
0[子线程]
1[子线程]
2[子线程]
3[子线程]
4[子线程]
5[子线程]
6[子线程]
7[子线程]
8[子线程]
9[子线程]
10[子线程]
11[子线程]
12[子线程]
13[子线程]
14[子线程]
15[子线程]
16[子线程]
17[子线程]
18[子线程]
19[子线程]

如果按照执行次序,本来应该最后打印的内容应该最后显示的,现在却放在最前头了。事实上,线程之间会互相争夺cpu资源,谁先抢到谁执行,像上述这种情况,则是主线程先抢到了cpu资源。如果必须保证先执行子线程,最后再执行主线程的打印动作的话,可以使用 join() 方法控制线程之间的执行次序。

我们再来实验一下主线程和单个子线程

public class condition {
public static void main(String[] args) { MyThread myThread = new MyThread();
myThread.setName("子线程");//设定子线程名字
myThread.start();
try {
myThread.join();
} catch (InterruptedException e) {
e.printStackTrace();
} System.out.println("主线程运行完毕");
}
} class MyThread extends Thread { @Override
public void run(){
for(int i=0;i<5;i++) {
System.out.println(i+"["+this.getName()+"]");
}
}
}

结果为

0[子线程]
1[子线程]
2[子线程]
3[子线程]
4[子线程]
主线程运行完毕

两个或多个子线程之间的顺序同样如此,

如果执行顺序限制为 【子线程1 → 子线程2 → 主线程结束】

public class condition {
public static void main(String[] args) { MyThread t1 = new MyThread("子线程1");
MyThread t2 = new MyThread("子线程2"); try {
t1.start();
t1.join();//join()方法只有在调用start()方法后使用才有意义
t2.start();
t2.join();
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("主线程结束");
}
} class MyThread extends Thread { public MyThread(String string) {
this.setName(string);
} @Override
public void run(){
for(int i=0;i<5;i++) {
System.out.println(i+"["+this.getName()+"]");
}
}
}

结果为:

0[子线程1]
1[子线程1]
2[子线程1]
3[子线程1]
4[子线程1]
0[子线程2]
1[子线程2]
2[子线程2]
3[子线程2]
4[子线程2]
主线程结束

参考:https://www.cnblogs.com/songshu120/p/7966314.html(多线程创建的三种方式)

【Java】多线程相关复习—— 线程的创建、名字、运行情况以及顺序控制(join方法) 【一】的更多相关文章

  1. Java多线程并发01——线程的创建与终止,你会几种方式

    本文开始将开始介绍 Java 多线程与并发相关的知识,多谢各位一直以来的关注与支持.关注我的公众号「Java面典」了解更多 Java 相关知识点. 线程的创建方式 在 Java 中,用户常用的主动创建 ...

  2. Java多线程并发02——线程的生命周期与常用方法,你都掌握了吗

    在上一章,为大家介绍了线程的一些基础知识,线程的创建与终止.本期将为各位带来线程的生命周期与常用方法.关注我的公众号「Java面典」了解更多 Java 相关知识点. 线程生命周期 一个线程不是被创建了 ...

  3. -1-5 java 多线程 概念 进程 线程区别联系 java创建线程方式 线程组 线程池概念 线程安全 同步 同步代码块 Lock锁 sleep()和wait()方法的区别 为什么wait(),notify(),notifyAll()等方法都定义在Object类中

     本文关键词: java 多线程 概念 进程 线程区别联系 java创建线程方式 线程组 线程池概念 线程安全 同步 同步代码块 Lock锁  sleep()和wait()方法的区别 为什么wait( ...

  4. Java多线程(三)如何创建线程

    点我跳过黑哥的卑鄙广告行为,进入正文. Java多线程系列更新中~ 正式篇: Java多线程(一) 什么是线程 Java多线程(二)关于多线程的CPU密集型和IO密集型这件事 Java多线程(三)如何 ...

  5. Java多线程相关的

    很多小伙伴在学习Java的时候,总是感觉Java多线程在实际的业务中很少使用,以至于不会花太多的时间去学习,技术债不断累积!等到了一定程度的时候对于与Java多线程相关的东西就很难理解,今天需要探讨的 ...

  6. Java多线程系列--“JUC线程池”06之 Callable和Future

    概要 本章介绍线程池中的Callable和Future.Callable 和 Future 简介示例和源码分析(基于JDK1.7.0_40) 转载请注明出处:http://www.cnblogs.co ...

  7. Java多线程系列--“JUC线程池”02之 线程池原理(一)

    概要 在上一章"Java多线程系列--“JUC线程池”01之 线程池架构"中,我们了解了线程池的架构.线程池的实现类是ThreadPoolExecutor类.本章,我们通过分析Th ...

  8. Java多线程系列--“JUC线程池”03之 线程池原理(二)

    概要 在前面一章"Java多线程系列--“JUC线程池”02之 线程池原理(一)"中介绍了线程池的数据结构,本章会通过分析线程池的源码,对线程池进行说明.内容包括:线程池示例参考代 ...

  9. Java多线程系列--“JUC线程池”04之 线程池原理(三)

    转载请注明出处:http://www.cnblogs.com/skywang12345/p/3509960.html 本章介绍线程池的生命周期.在"Java多线程系列--“基础篇”01之 基 ...

随机推荐

  1. [inner] bug

    这样正确 command: ["sh", "-c", "mysql -h${DC_DB_HOST} -uroot -p${MYSQL_ROOT_PAS ...

  2. Linux证书登录,禁用密码

    如果验证成功的话就可以关闭密码登陆方式了, 编辑/etc/ssh/sshd_config, 将PasswordAuthentication改为no, ChallengeResponseAuthenti ...

  3. Intellij IDEA 14 自动生成 serialVersionUID

    1.  Preferences > Editor > Inspections > Java > Serialization issues > Serializable c ...

  4. Spring boot-(2) Spring Boot使用

    1. 构建系统 (1) 使用maven构建 1) 从Starter Parent继承 在项目中配置继承spring-boot-starter-parent,可以进行如下设置: <!-- Inhe ...

  5. Quartz使用(2) - Quartz核心接口Scheduler、Job

    quartz的核心接口如下: 接口 含义 Scheduler scheduler的主要API接口 Job 任务实现接口,期望调度器能够执行 JobDetail 用于定义Job实例 Trigger 调度 ...

  6. 打乱式排序的Java版实现

    项目中涉及到对大批量的数据进行打乱式排序,大概原理如下: 输入源数据:1,1,2,3,3,3,4,4 输出结果:   1,2,3,4,1,3,4,3 实现代码如下,采用递归的思想: static &l ...

  7. php 设置虚拟目录

    php 设置虚拟目录两个步骤,很简单. 第一,打开安装apache目录下的conf下面的httpd.conf文件.   找到IfModule 标记, 再它下面添加红色方框中的内容.注意不能少东西.   ...

  8. web子项目的路径问题

    http://baidu.com/userms/ userms是一个子应用程序,项目中使用的路径 /content/css/..   从http://baidu.com/  开始 ~/content/ ...

  9. 小程序封装一个ajax

    小程序中,我们一般习惯把提交接口请求的方法放在一个公共js里面.下面是一个简单实现. (1)我们把所有请求的地址都放在一个json里面 var postAddress = { "domin& ...

  10. 在快速自定义的NopCommerce中使用实体框架(EF)代码优先迁移

    我看到很多nopCommerce论坛的用户问他们如何使用Entity Framework(EF)代码优先迁移来自定义nopCommerce,添加新的字段和entites核心.我实际上在做nopComm ...