Thread类中的方法调用方式:

学习Thread类中的方法是学习多线程的第一步。在学习多线程之前特别提出一点,调用Thread中的方法的时候,在线程类中,有两种方式,一定要理解这两种方式的区别:

1、this.XXX() 和 线程对象实例.XXX() 这里要首先参考 多线程 Thread.currentThread().getName() ,对象实例.getName() 和 this.getName()区别 理解采用Thread继承实现线程的几种启动方式出现的问题

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

2、Thread.currentThread.XXX()或Thread.XXX() 这里一个是获取当前线程实例调用实例方法,一个是调用当前线程的静态的方法,都是指向当前调用方法的线程

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

当然,这么说,肯定有人不理解两者之间的差别。没有关系,之后会讲清楚,尤其是在讲Thread构造函数这块。讲解后,再回过头来看上面2点,会加深理解。

Thread类中的实例方法

从Thread类中的实例方法和类方法的角度讲解Thread中的方法,这种区分的角度也有助于理解多线程中的方法。实例方法,只和实例线程(也就是new出来的线程)本身挂钩,和当前运行的是哪个线程无关。看下Thread类中的实例方法:

1、start()

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

public class MyThread02 extends Thread
{
public void run()
{
try
{
for (int i = 0; i < 3; i++)
{
Thread.sleep((int)(Math.random() * 1000));
System.out.println("run = " + Thread.currentThread().getName());
}
}
catch (InterruptedException e)
{
e.printStackTrace();
}
}
}
public static void main(String[] args)
{
MyThread02 mt = new MyThread02();
mt.start(); try
{
for (int i = 0; i < 3; i++)
{
Thread.sleep((int)(Math.random() * 1000));
System.out.println("run = " + Thread.currentThread().getName());
}
}
catch (InterruptedException e)
{
e.printStackTrace();
}
}

看下运行结果:

run = Thread-0
run = main
run = main
run = main
run = Thread-0
run = Thread-0

结果表明了:CPU执行哪个线程的代码具有不确定性。再看另外一个例子:

public class MyThread03 extends Thread
{
public void run()
{
System.out.println(Thread.currentThread().getName());
}
}
public static void main(String[] args)
{
MyThread03 mt0 = new MyThread03();
MyThread03 mt1 = new MyThread03();
MyThread03 mt2 = new MyThread03(); mt0.start();
mt1.start();
mt2.start();
}

看下运行结果:

Thread-1
Thread-2
Thread-0

尽管启动线程是按照mt0、mt1、mt2,但是实际的启动顺序却是Thread-1、Thread-2、Thread-0。这个例子说明了:调用start()方法的顺序不代表线程启动的顺序,线程启动顺序具有不确定性

关于start线程可以了解下多线程 Thread.currentThread().getName() ,对象实例.getName() 和 this.getName()区别 理解采用Thread继承实现线程的几种启动方式出现的问题

2、run()

线程开始执行,虚拟机调用的是线程run()方法中的内容。稍微改一下之前的例子看一下:

public static void main(String[] args)
{
MyThread02 mt = new MyThread02();
mt.run(); try
{
for (int i = 0; i < 3; i++)
{
Thread.sleep((int)(Math.random() * 1000));
System.out.println("run = " + Thread.currentThread().getName());
}
}
catch (InterruptedException e)
{
e.printStackTrace();
}
}

MyThread02的代码不变,看下运行结果:

run = main
run = main
run = main
run = main
run = main
run = main

看到打印了6次的"run = main",说明如果只有run()没有start(),Thread实例run()方法里面的内容是没有任何异步效果的,全部被main函数执行。换句话说,只有run()而不调用start()启动线程是没有任何意义的。

3、isAlive()

测试线程是否处于活动状态,只要线程启动且没有终止,方法返回的就是true。看一下例子:

public class MyThread06 extends Thread
{
public void run()
{
System.out.println("run = " + this.isAlive());
}
}
public static void main(String[] args) throws Exception
{
MyThread06 mt = new MyThread06();
System.out.println("begin == " + mt.isAlive());
mt.start();
Thread.sleep(100);
System.out.println("end == " + mt.isAlive());
}

看下运行结果:

begin == false
run = true
end == false

看到在start()之前,线程的isAlive是false,start()之后就是true了。main函数中加上Thread.sleep(100)的原因是为了确保Thread06的run()方法中的代码执行完,否则有可能end这里打印出来的是true,有兴趣可以自己试验一下。

isAlive() 备注下

也就是 无论什么情况  sleep  wait 等 只要是还没结束  那isAlive()都是存活的

4、getId()

这个方法比较简单,就不写例子了。在一个Java应用中,有一个long型的全局唯一的线程ID生成器threadSeqNumber,每new出来一个线程都会把这个自增一次,并赋予线程的tid属性,这个是Thread自己做的,用户无法执行一个线程的Id。

5、getName()

这个方法也比较简单,也不写例子了。我们new一个线程的时候,可以指定该线程的名字,也可以不指定。如果指定,那么线程的名字就是我们自己指定的,getName()返回的也是开发者指定的线程的名字;如果不指定,那么Thread中有一个int型全局唯一的线程初始号生成器threadInitNum,Java先把threadInitNum自增,然后以"Thread-threadInitNum"的方式来命名新生成的线程

6、getPriority()和setPriority(int newPriority)

参考 java 多线程4: java线程的优先级

7、isDaeMon、setDaemon(boolean on)

讲解两个方法前,首先要知道理解一个概念。Java中有两种线程,一种是用户线程,一种是守护线程。守护线程是一种特殊的线程,它的作用是为其他线程的运行提供便利的服务,最典型的应用便是GC线程。如果进程中不存在非守护线程了,那么守护线程自动销毁,因为没有存在的必要,为别人服务,结果服务的对象都没了,当然就销毁了。

理解了这个概念后,看一下例子

public class MyThread11 extends Thread
{
private int i = 0; public void run()
{
try
{
while (true)
{
i++;
System.out.println("i = " + i);
Thread.sleep(1000);
}
}
catch (InterruptedException e)
{
e.printStackTrace();
}
}
}
public static void main(String[] args)
{
try
{
MyThread11 mt = new MyThread11();
mt.setDaemon(true);
mt.start();
Thread.sleep(5000);
System.out.println("我离开thread对象再也不打印了,我停止了!");
}
catch (InterruptedException e)
{
e.printStackTrace();
}
}

看一下运行结果:

 1 i = 1
2 i = 2
3 i = 3
4 i = 4
5 i = 5
6 我离开thread对象再也不打印了,我停止了!
7 i = 6

要解释一下。我们将MyThread11线程设置为守护线程,看到第6行的那句话,而i停在6不会再运行了。这说明,main线程运行了5秒多结束,而i每隔1秒累加一次,5秒后main线程执行完结束了,MyThread11作为守护线程,main函数都运行完了,自然也没有存在的必要了,就自动销毁了,因此也就没有再往下打印数字。

关于守护线程,有一个细节注意下,setDaemon(true)必须在线程start()之前

8、interrupt()

9、isInterrupted()

以上两个方法请转移

java 多线程5: java 终止线程及中断机制 (stop()、interrupt() 、interrupted()、isInterrupted())

java 多线程6: 中断机制 优雅的终止java线程  这两篇文章

10、join()

参考java多线程16:join()的使用

11.stop() 停止方法  已废弃

12.suspend() 和 resume() 暂停和恢复 ,已废弃

参考 java 多线程7: (suspend方法与resume方法) 挂起与恢复


java 多线程2:Thread的实例方法的更多相关文章

  1. Java 多线程(1)-Thread和Runnable

    一提到Java多线程,首先想到的是Thread继承和Runnable的接口实现 Thread继承 public class MyThread extends Thread { public void ...

  2. Java多线程01(Thread类、线程创建、线程池)

    Java多线程(Thread类.线程创建.线程池) 第一章 多线程 1.1 多线程介绍 1.1.1 基本概念 进程:进程指正在运行的程序.确切的来说,当一个程序进入内存运行,即变成一个进程,进程是处于 ...

  3. JAVA多线程(一) Thread & Runnable

    githut代码地址:https://github.com/showkawa/springBoot_2017/tree/master/spb-demo/spb-brian-query-service/ ...

  4. java多线程创建-Thread,Runnable,callable和threadpool

    java创建多线程的方式有许多种,这里简要做个梳理 1. 继承Thread类 继承java.lang.Thread类,创建本地多线程的类,重载run()方法,调用Thread的方法启动线程.示例代码如 ...

  5. Java 多线程之 Thread 类 和 Runnable 接口初步使用

    目录 Thread 类 Thread之定义线程类 Thread之开启线程 Runnable 接口 Runnable 之定义线程类 Runnable 之开启线程 @ Thread 类 Thread 类是 ...

  6. Java 多线程(Thread)学习

    多线程:就是进程的扩展,实现并发.一个进程可以包含多个线程,进程一般是由操作系统控制,而线程就是由程序员控制的,所以作为编程人员做好线程是我们的重点. 线程和进程一样分为五个阶段:创建.就绪.运行.阻 ...

  7. java 多线程:Thread 并发线程: 方法同步synchronized关键字,与static的结合

    1.方法内的变量是安全的 方法内定义的变量,每个变量对应单独的内存变量地址,多个线程之间相互不影响.多个线程之间的变量根本没有一毛钱关系 public class ThreadFuncVarSafe ...

  8. java 多线程:Thread类常用方法:setPriority优先级、interrupt中断标记、suspend暂停与唤醒resume(已过时);daemon守护线程

    常用方法: boolean isAlive() 测试此线程是否存活. boolean isDaemon() 测试此线程是否为守护程序线程. static void sleep?(long millis ...

  9. java 多线程:Thread类;Runnable接口

    1,进程和线程的基本概念: 1.什么是进程: 进程(Process)是计算机中的程序关于某数据集合上的一次运行活动,是系统进行资源分配和调度的基本单位,是操作系统结构的基础.在早期面向进程设计的计算机 ...

  10. Java 多线程 (Thread 类)

    1.多线程 2.卖票 1.多线程实现 两种方式可以实现多线程: 继承 Thread 类,重写 run 方法:定义对象,调用 start 方法 创建类实现 Runnable 接口,作为实参传递给 thr ...

随机推荐

  1. 批处理文件:将目录下所有的jar文件都加到CLASSPATH

    简便写法如下: 代码 : @echo off SetLocal EnableDelayedExpansion FOR %%i IN ("XXX\lib\*.jar") DO SET ...

  2. 腾讯云-Linux 基础入门

    Linux 基础入门 目录操作 任务时间:5min ~ 10min 创建目录 使用 mkdir 命令创建目录 mkdir $HOME/testFolder # $HOME 当前用户的家目录  root ...

  3. jQuery写一个简单的弹幕墙

    概述 近几年由于直播,弹幕流行起来,之前看到过用js制作弹幕墙的思路,觉得很有趣.自己就花了点时间把他做成了更灵活的jQuery插件,现在分享出来. 详细 代码下载:http://www.demoda ...

  4. 140730暑期培训.txt

    1.大数加减法    思路分析:        1.将数据当做字符串输入(gets(s))        2.将字符型转换为整型,逆着存            char? int      i=0,j ...

  5. aop注解 自定义切面的注解写法

    spring.xml中 <?xml version="1.0" encoding="UTF-8"?> <beans xmlns="h ...

  6. servlet下根据相对路径找资源

    1.在web项目中如果直接添加一个资源,那么相对路径相对的是tomcat的bin目录. 2.在包中直接指定资源,那么可以使用以下的相对路径直接获取资源: InputStream in = this.g ...

  7. 设置sqlplus访问远程oracle数据库的最快方法

    设置sqlplus访问远程oracle数据库的最快方法 时间:2010-01-21 10:57来源: 作者: 点击: 2次 设置sqlplus访问远程oracle数据库的最快方法,如果要连接远程数据库 ...

  8. 【LeetCode】164. Maximum Gap (2 solutions)

    Maximum Gap Given an unsorted array, find the maximum difference between the successive elements in ...

  9. Windows2008R2允许多用户远程登录设置

    Windows 2008 R2终端服务器安装配置 后面的一律下一步就可以安装完成了,下面是如何设置多用户远程登陆. Windows2008允许多用户远程登录设置 服务器重启,以上配置全部生效.

  10. 整理mysql的28个知识点(转)

    版权声明:本文为博主原创文章,未经博主允许不得转载. https://blog.csdn.net/weixin_39220472/article/details/80247011整理mysql28个知 ...