1、start()

  • start()方法的作用讲得直白点就是通知"线程规划器",此线程可以运行了,正在等待CPU调用线程对象得run()方法,产生一个异步执行的效果。通过start()方法产生得到结论,先看下代码:
/**
* @author zs
* @date 2019/9/20 10:13
*/
public class MyTicketThread extends Thread {
private int ticket=5;//仅剩五张票
public MyTicketThread(String threadName) {
super(threadName);//调用父类的带参构造方法
} @Override
public void run() { // TODO Auto-generated method stub
for(int i=0;i<100;i++){
synchronized (this) {
if(ticket>0){
try {
Thread.sleep(300);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
System.out.println(Thread.currentThread().getName() + "卖第"
+ (ticket--) + "张票");
}
}
}
}
}
/**
* @author zs
* @date 2019/9/20 10:14
*/
public class Test {
public static void main(String[] args) {
//4个窗口
MyTicketThread t1=new MyTicketThread("A窗口");
MyTicketThread t2=new MyTicketThread("B窗口");
MyTicketThread t3=new MyTicketThread("C窗口");
MyTicketThread t4=new MyTicketThread("D窗口");
//启动线程
t1.start();
t2.start();
t3.start();
t4.start();
}
}

运行结果:

B窗口卖第5张票
C窗口卖第5张票
D窗口卖第5张票
A窗口卖第5张票
D窗口卖第4张票
A窗口卖第4张票
B窗口卖第4张票
C窗口卖第4张票
D窗口卖第3张票
A窗口卖第3张票

...

 
  • 解释:可以看出,线程执行的先后顺序,是不确定的。

2、currentThread()

currentThread()方法返回的是对当前正在执行线程对象的引用

在线程类中,有两种方式,一定要理解这两种方式的区别:

(1)this.XXX()

这种调用方式表示的线程是线程实例本身

(2)Thread.currentThread.XXX()或Thread.XXX()

上面两种写法是一样的意思。这种调用方式表示的线程是正在执行Thread.currentThread.XXX()所在代码块的线程

下面通过看一个重要的例子,然后得出结论:

public class MyThread04 extends Thread
{
static
{
System.out.println("静态块的打印:" +
Thread.currentThread().getName());
} public MyThread04()
{
System.out.println("构造方法的打印:" +
Thread.currentThread().getName());
} public void run()
{
System.out.println("run()方法的打印:" +
Thread.currentThread().getName());
}
}
public static void main(String[] args)
{
MyThread04 mt = new MyThread04();
mt.start();
}

看一下运行结果:

静态块的打印:main
构造方法的打印:main
run()方法的打印:Thread-0

这个例子说明了,线程类的构造方法、静态块是被main线程调用的,而线程类的run()方法才是应用线程自己调用的。在这个例子的基础上,再深入:

public class MyThread05 extends Thread
{
public MyThread05()
{
System.out.println("MyThread5----->Begin");
System.out.println("Thread.currentThread().getName()----->" +
Thread.currentThread().getName());
System.out.println("this.getName()----->" + this.getName());
System.out.println("MyThread5----->end");
} public void run()
{
System.out.println("run----->Begin");
System.out.println("Thread.currentThread().getName()----->" +
Thread.currentThread().getName());
System.out.println("this.getName()----->" + this.getName());
System.out.println("run----->end");
}
}
public static void main(String[] args)
{
MyThread05 mt5 = new MyThread05();
mt5.start();
}

看一下运行结果:

MyThread5----->Begin
Thread.currentThread().getName()----->main
this.getName()----->Thread-0
MyThread5----->end
run----->Begin
Thread.currentThread().getName()----->Thread-0
this.getName()----->Thread-0
run----->end

可以看出:当前执行的Thread未必就是Thread本身。从这个例子就能看出来:

(1)执行MyThread05构造方法是main,当前线程却是Thread-0

(2)执行run()方法的Thread-0,当前线程也是Thread-0,说明run()方法就是被线程实例去执行的

所以,再强调一下,未必在MyThread05里调用Thread.currentThread()返回回来的线程对象的引用就是MyThread05。

3、sleep(long millis)

sleep(long millis)方法的作用是在指定的毫秒内让当前"正在执行的线程"休眠(暂停执行)。这个"正在执行的线程"是关键,指的是Thread.currentThread()返回的线程。根据JDK API的说法,"该线程不丢失任何监视器的所属权",简单说就是sleep代码上下文如果被加锁了,锁依然在,但是CPU资源会让出给其他线程。看一下例子:

public class MyThread07 extends Thread
{
public void run()
{
try
{
System.out.println("run threadName = " +
this.getName() + " begin");
Thread.sleep(2000);
System.out.println("run threadName = " +
this.getName() + " end");
}
catch (InterruptedException e)
{
e.printStackTrace();
}
}
}
public static void main(String[] args)
{
MyThread07 mt = new MyThread07();
System.out.println("begin = " + System.currentTimeMillis());
mt.start();
System.out.println("end = " + System.currentTimeMillis());
}

看一下运行结果:

begin = 1443694780609
end = 1443694780609
run threadName = Thread-0 begin
run threadName = Thread-0 end

当然,因为打印结果是静态的,所以只能看出异步执行的效果,看不出sleep(long millis)方法执行的效果。实际上第3句打出2秒后打出第4句,这和run()方法里面的sleep(2000)是对应的

4、yield()

暂停当前执行的线程对象,并执行其他线程。这个暂停是会放弃CPU资源的,并且放弃CPU的时间不确定,有可能刚放弃,就获得CPU资源了,也有可能放弃好一会儿,才会被CPU执行。看一下例子:

public class MyThread08 extends Thread
{
public void run()
{
long beginTime = System.currentTimeMillis();
int count = 0;
for (int i = 0; i < 50000000; i++)
{
Thread.yield();
count = count + i + 1;
}
long endTime = System.currentTimeMillis();
System.out.println("用时:" + (endTime - beginTime) + "毫秒!");
}
}
public static void main(String[] args)
{
MyThread08 mt = new MyThread08();
mt.start();
}

看一下运行结果:

用时:3264毫秒!
用时:3299毫秒!
用时:3232毫秒!
用时:3256毫秒!
用时:3283毫秒!
用时:3504毫秒!
用时:3378毫秒!

看到,每次执行的用时都不一样,证明了yield()方法放弃CPU的时间并不确定。

5、注意

1、sleep()和wait()方法的区别,三点:

  1. sleep()是Thread中的方法,线程休眠;wait()是Object中的方法,线程等待;
  2. 都导致线程的阻塞;
  3. sleep()对对象所持有的锁不释放,wait()释放所持有的锁;

2、Java中Wait、Sleep和Yield方法的区别

  • wait()是Object的方法,用于线程间的通信,线程等待,进入阻塞状态,会释放锁;
  • sleep是Thread的静态方法,调用该方法,令当前线程休眠,进入阻塞状态,不会释放锁;
  • yield和sleep的主要是,yield方法会临时暂停当前正在执行的线程,来让有同样优先级的正在等待的线程有机会执行。如果没有正在等待的线程,或者所有正在等待的线程的优先级都比较低,那么该线程会继续运行。执行了yield方法的线程什么时候会继续运行由线程调度器来决定,不同的厂商可能有不同的行为。yield方法不保证当前的线程会暂停或者停止,但是可以保证当前线程在调用yield方法时会放弃CPU。

(二)线程Thread中的方法详解的更多相关文章

  1. 线程Thread中的方法详解(二)

    1.start() start()方法的作用讲得直白点就是通知"线程规划器",此线程可以运行了,正在等待CPU调用线程对象得run()方法,产生一个异步执行的效果.通过start( ...

  2. JavaScript正则表达式详解(二)JavaScript中正则表达式函数详解

    二.JavaScript中正则表达式函数详解(exec, test, match, replace, search, split) 1.使用正则表达式的方法去匹配查找字符串 1.1. exec方法详解 ...

  3. angularJS中$apply()方法详解

    这篇文章主要介绍了angularJS中$apply()方法详解,需要的朋友可以参考下   对于一个在前端属于纯新手的我来说,Javascript都还是一知半解,要想直接上手angular JS,遇到的 ...

  4. jQuery中 $.ajax()方法详解

    $.ajax()方法详解 jquery中的ajax方法参数总是记不住,这里记录一下. 1.url: 要求为String类型的参数,(默认为当前页地址)发送请求的地址. 2.type: 要求为Strin ...

  5. MySQL服务器线程数的查看方法详解

    本文实例讲述了MySQL服务器线程数的查看方法.分享给大家供大家参考,具体如下: mysql重启命令: ? 1 /etc/init.d/mysql restart MySQL服务器的线程数需要在一个合 ...

  6. Java多线程中join方法详解

    join()方法用于让当前执行线程等待join线程执行结束.其实现原理是不停的检查join线程是否存活,如果join线程存活则让当前线程永远等待. join()方法部分实现细节 while(isAli ...

  7. Java中常见方法详解合集(方法的定义及语法结构)

    Java的方法定义 1.方法的定义 方法是控制对象的动作行为方式与准则,在Java中方法位于类体下又有另一种含义. 普通的方法在类中称为"实例方法",因为方法的调用需要创建对象,而 ...

  8. boost库中sleep方法详解

    博客转载自:https://blog.csdn.net/huang_xw/article/details/8453506 boost库中sleep有两个方法: 1. 这个方法只能在线程中用, 在主线程 ...

  9. JavaScript中getBoundingClientRect()方法详解

    获取浏览器滚动的高度: scrollTop=document.documentElement.scrollTop || document.body.scrollTop getBoundingClien ...

随机推荐

  1. python基础关键词触发的魔法方法

    with: __enter__ __exit__ dic={} 获取容器中指定元素的行为 dic["name"] = "egon" #设置值 __setitem ...

  2. restful规范与rest_framework

    django两种开发模式: 一.前后端不分离项目 二.前后端分离项目 什么是restful规范? 在前后端不分离的项目中,网页所需要的数据可以直接通过模板渲染的方式传递到前端页面,并且可以很好的支持d ...

  3. java学习(东软睿道)2019-09-06(预课)《随堂笔记》

    2019-09-06 13:19:56 1.变量:java  名称 2.服务器server 客户端client                         uft8   ascll 3.Java ...

  4. oracle杀死正在执行的进程

    1 查询目前正在执行的终端和进程, SELECT /*+ rule */ s.username,decode(l.type,'TM','TABLE LOCK','TX','ROW LOCK',NULL ...

  5. springboot简易上传下载

    1.导入上传下载依赖: <dependency> <groupId>commons-fileupload</groupId> <artifactId>c ...

  6. Netty源码剖析-发送数据

    参考文献:极客时间傅健老师的<Netty源码剖析与实战>Talk is cheap.show me the code! 开始之前先介绍下Netty写数据的三种方式: ①:write:写到一 ...

  7. HDU - 2196(树形DP)

    题目: A school bought the first computer some time ago(so this computer's id is 1). During the recent ...

  8. python学习-4 python基础-2 条件语句(if的简单用法1)

    条件语句的原理: 2.举个例子:比大小 #!/usr/bin/env python # -*- coding:utf8 -*- a=input("请输入a:") b=input(& ...

  9. Algorithm negotiation failed

    #用pycharm工具ssh client 报 algorithm negotiation failed#导致原因:是ssh升级后,为了安全,默认不再采用原来一些加密算法,我们手工添加进去即可#目前出 ...

  10. 植物大战僵尸:查找植物叠加种植CALL

    实验目标:我们都知道植物大战僵尸游戏中植物是不可以叠加种植的,也就是一个格子只能种植一个植物,今天我们将实现一个格子里种植无限多的植物. 我们首先需要找到植物的种植CALL,然后在逐步测试观察功能之间 ...