Java并发编程:Java Thread 的 sleep() 和 wait() 的区别
1. start 和 run 方法解释:
用start方法来启动线程,真正实现了多线程运行,这时无需等待run方法体代码执行完毕而直接继续执行下面的代码。通过调用Thread类的start()方法来启动一个线程,这时此线程处于就绪(可运行)状态,并没有运行,一旦得到cpu时间片,就开始执行run()方法,这里方法 run()称为线程体,它包含了要执行的这个线程的内容,Run方法运行结束,此线程随即终止。
2) run:
run()方法只是类的一个普通方法而已,如果直接调用Run方法,程序中依然只有主线程这一个线程,其程序执行路径还是只有一条,还是要顺序执行,还是要等待run方法体执行完毕后才可继续执行下面的代码,这样就没有达到写线程的目的。总结:调用start方法方可启动线程,而run方法只是thread的一个普通方法调用,还是在主线程里执行。这两个方法应该都比较熟悉,把需要并行处理的代码放在run()方法中,start()方法启动线程将自动调用 run()方法,这是由jvm的内存机制规定的。并且run()方法必须是public访问权限,返回值类型为void。
2. 对Java线程的补充说明:
Java 的线程是通过java.lang.Thread类来实现的。VM启动时会有一个由主方法所定义的线程。可以通过创建Thread的实例来创建新的线程。每个线程都是通过某个特定Thread对象所对应的方法run()来完成其操作的,方法run()称为线程体。通过调用Thread类的start()方法来启动一个线程。
在Java 当中,线程通常都有五种状态,创建、就绪、运行、阻塞和死亡。
第一是创建状态。在生成线程对象,并没有调用该对象的start方法,这是线程处于创建状态。
第二是就绪状态。当调用了线程对象的start方法之后,该线程就进入了就绪状态,但是此时线程调度程序还没有把该线程设置为当前线程,此时处于就绪状态。在线程运行之后,从等待或者睡眠中回来之后,也会处于就绪状态。
第三是运行状态。线程调度程序将处于就绪状态的线程设置为当前线程,此时线程就进入了运行状态,开始运行run函数当中的代码。
第四是阻塞状态。线程正在运行的时候,被暂停,通常是为了等待某个时间的发生(比如说某项资源就绪)之后再继续运行。sleep,suspend,wait等方法都可以导致线程阻塞。
第五是死亡状态。如果一个线程的run方法执行结束或者调用stop方法后,该线程就会死亡。对于已经死亡的线程,无法再使用start方法令其进入就绪。
实现并启动线程有两种方法
1、写一个类继承自Thread类,重写run方法。用start方法启动线程
2、写一个类实现Runnable接口,实现run方法。用new Thread(Runnable target).start()方法来启动
多线程原理:相当于玩游戏机,只有一个游戏机(cpu),可是有很多人要玩,于是,start是排队!等CPU选中你就是轮到你,你就run(),当CPU的运行的时间片执行完,这个线程就继续排队,等待下一次的run()。
调用start()后,线程会被放到等待队列,等待CPU调度,并不一定要马上开始执行,只是将这个线程置于可动行状态。然后通过JVM,线程Thread会调用run()方法,执行本线程的线程体。先调用start后调用run,这么麻烦,为了不直接调用run?就是为了实现多线程的优点,没这个start不行。
1.start()方法来启动线程,真正实现了多线程运行。这时无需等待run方法体代码执行完毕,可以直接继续执行下面的代码;通过调用Thread类的start()方法来启动一个线程, 这时此线程是处于就绪状态, 并没有运行。 然后通过此Thread类调用方法run()来完成其运行操作的, 这里方法run()称为线程体,它包含了要执行的这个线程的内容, Run方法运行结束, 此线程终止。然后CPU再调度其它线程。
2.run()方法当作普通方法的方式调用。程序还是要顺序执行,要等待run方法体执行完毕后,才可继续执行下面的代码; 程序中只有主线程——这一个线程, 其程序执行路径还是只有一条, 这样就没有达到写线程的目的。
记住:多线程就是分时利用CPU,宏观上让所有线程一起执行 ,也叫并发。
3. 实例
package com.threadDemo.runDemo; public class RunDemo { public static void main(String[] args) {
System.out.println("主线程ID:" + Thread.currentThread().getId());
MyThread thread1 = new MyThread("thread1");
thread1.start();
MyThread thread2 = new MyThread("thread2");
thread2.run();
}
} class MyThread extends Thread {
private String name; public MyThread(String name) {
this.name = name;
} @Override
public void run() {
System.out.println("name:" + name + " 子线程ID:" + Thread.currentThread().getId());
}
}
执行结果如下
主线程ID:1
name:thread1 子线程ID:11
name:thread2 子线程ID:1
从输出结果可以得出以下结论:
1)thread1和thread2的线程ID不同,thread2和主线程ID相同,说明通过run方法调用并不会创建新的线程,而是在主线程中直接运行run方法,跟普通的方法调用没有任何区别;
2)虽然thread1的start方法调用在thread2的run方法前面调用,但是先输出的是thread2的run方法调用的相关信息,说明新线程创建的过程不会阻塞主线程的后续执行。
Java并发编程:Java Thread 的 sleep() 和 wait() 的区别的更多相关文章
- Java并发编程:Thread类的使用
Java并发编程:Thread类的使用 在前面2篇文章分别讲到了线程和进程的由来.以及如何在Java中怎么创建线程和进程.今天我们来学习一下Thread类,在学习Thread类之前,先介绍与线程相关知 ...
- 【转】Java并发编程:Thread类的使用
一.线程的状态 在正式学习Thread类中的具体方法之前,我们先来了解一下线程有哪些状态,这个将会有助于对Thread类中的方法的理解. 线程从创建到最终的消亡,要经历若干个状态.一般来说,线程包括以 ...
- 3、Java并发编程:Thread类的使用
Java并发编程:Thread类的使用 在前面2篇文章分别讲到了线程和进程的由来.以及如何在Java中怎么创建线程和进程.今天我们来学习一下Thread类,在学习Thread类之前,先介绍与线程相关知 ...
- Java并发编程-Java内存模型
JVM内存结构与Java内存模型经常会混淆在一起,本文将对Java内存模型进行详细说明,并解释Java内存模型在线程通信方面起到的作用. 我们常说的JVM内存模式指的是JVM的内存分区:而Java内存 ...
- Java并发编程:Thread类的使用介绍
在学习Thread类之前,先介绍与线程相关知识:线程的几种状态.上下文切换,然后接着介绍Thread类中的方法的具体使用. 以下是本文的目录大纲: 一.线程的状态 二.上下文切换 三.Thread类中 ...
- Java并发编程:Thread类的使用(转载)
一:线程的状态: 在正式学习Thread类中的具体方法之前,我们先来了解一下线程有哪些状态,这个将会有助于后面对Thread类中的方法的理解. 线程从创建到最终的消亡,要经历若干个状态.一般来说,线程 ...
- Java并发编程:Java Thread 的 run() 与 start() 的区别
1. sleep 和 wait 方法解释 sleep()方法是Thread类里面的,主要的意义就是让当前线程停止执行,让出cpu给其他的线程,但是不会释放对象锁资源以及监控的状态,当指定的时间到了之后 ...
- Java并发编程--1.Thread和Runnable
创建线程 Java有两种方式创建线程, 继承Thread类和实现Runnable接口 继承Thread 步骤: 1.自定义一个类继承Thread类, 重写run方法 2.创建自定义类的对象,调用sta ...
- Java并发编程:Java Thread方法join的简单总结
虽然关于讨论线程join方法的博客已经很多了,不过个人感觉挺多都讨论得不够全面,所以我觉得有必要对其进行一个全面的总结. 一.作用 Thread类中的join方法的主要作用就是同步,它可以使得线程之间 ...
随机推荐
- DelphiXE7 Datasnap TDSClientCallbackChannelManager内部实现初探
回调的原理很简单,开一个线程(为了区别其它线程,先将此线程命名为“通道线程”),注册一个“轻量”的回调,然后此线程(通道线程)等服务器返回信息(回调),服务器有信息返回时,通道线程再开个线程执行用户注 ...
- JDK1.8中如何用ScriptEngine动态执行JS
JDK1.8中如何用ScriptEngine动态执行JS jdk1.6开始就提供了动态脚本语言诸如JavaScript动态的支持.这无疑是一个很好的功能,毕竟Java的语法不是适合成为动态语言.而JD ...
- Tensorflow之基于MNIST手写识别的入门介绍
Tensorflow是当下AI热潮下,最为受欢迎的开源框架.无论是从Github上的fork数量还是star数量,还是从支持的语音,开发资料,社区活跃度等多方面,他当之为superstar. 在前面介 ...
- ML: 聚类算法R包-网格聚类
网格聚类算法 optpart::clique optpart::clique CLIQUE(Clustering In QUEst)是一种简单的基于网格的聚类方法,用于发现子空间中基于密度的簇.CLI ...
- DOM confirm setTimeout url刷新
console.log 输出框 alert 弹出框 confirm 确认框 // URL和刷新 location.href 获取URL location.href = "url" ...
- VS2012打开项目——已停止工作
VS2012打开项目——已停止工作 解决方法如下: 1. 开始-->所有程序-->Microsoft Visual Studio 2012-->Visual Studio Tools ...
- VS2010 如何自动生成UML图
项目名---右键----查看类图
- 在Python中进行自动化单元测试的教程
From: https://www.jb51.net/article/64119.htm 一.软件测试 大型软件系统的开发是一个很复杂的过程,其中因为人的因素而所产生的错误非常多,因此软件在开发过程必 ...
- Javascript中变量提升的问题(五)
一.函数声明变量提升 函数声明具有变量提升的问题,所以在函数被声明之前就可以访问. console.log(getValue()); function getValue() { return 'a ...
- nginx 操作笔记
测试nginx 配置是否成功 service nginx configtest