1. 多线程使用方法

使用多线程,绝大部分情况都是通过如下两种方式实现的,即继承Thread类或者实现Runnable接口。以下对两种方式分别进行介绍并比较。

1.1 使用Thread类实现多线程

自定义线程类要继承 Thread 类,并在 run 方法中实现自己的逻辑。参数的传递,可以采用构造方法传参或者设值的方式。

public class MyThread extends Thread

{

private String name;

public MyThread(String name)

{

this.name = name;

}

public void run()

{

for (int i = 0;i < 5;i++)

{

System.out.println("Thread name is " + name + ", say hello " + i);

try

{

Thread.sleep(500);

}

catch (InterruptedException e)

{

e.printStackTrace();

}

}

}

public static void main(String[] args)

{

Thread alice = new MyThread("Alice");

Thread bob = new MyThread("Bob");

alice.start();

bob.start();

}

}

1.2 使用Runnable接口实现多线程

自定义线程类要实现 Runnable 接口,重写 run 方法。参数的传递,可以采用构造方法传参或者设值的方式。

package com.example.demo.mutilThread;

public class MyRunnable implements Runnable

{

private String name;

public MyRunnable(String name)

{

this.name = name;

}

public void run()

{

for (int i = 0;i < 5;i++)

{

System.out.println("RunnableThread name is " + name + ", say hello " + i);

try

{

Thread.sleep(500);

}

catch (InterruptedException e)

{

e.printStackTrace();

}

}

}

public static void main(String[] args)

{

Thread cache = new Thread(new MyRunnable("Cache"));

Thread dodge = new Thread(new MyRunnable("Dodge"));

cache.start();

dodge.start();

}

}

1.3 小结

线程创建完毕之后,调用Thread的start方法,该并不是直接开始执行该线程,而是将该线程设置成为可运行的状态,即随时都都可以运行。至于什么时候真正的开始运行,是由操作系统的调度决定的。

在自定义线程类中重写的是run方法,但是在使用多线程的时候,调用的是start方法。打开start方法的实现,可以看到其中调用了本地方法start0,而在该方法中,最终调用了线程实例的run方法。如果在主线程中不使用start,而是使用run方法,那么则不会新开辟一个线程来执行其中的逻辑,而是直接在主线程中执行,跟普通的方法一样。

通过执行结果可以看到,多个线程之间的程序执行是乱序的,并不是每个线程按照某种固定的顺序执行。但是可以通过设计对应的控制逻辑,使得多个线程的执行变得有序。

对比两种方式,其实更加推荐使用Runnable的方式,因为实现Runnable接口,可以规避java中的单继承的限制,并且对于线程池来说,不能直接放入继承Thread的类。另外,Runnable的代码可以被多个线程共享(即用一个Runnable实现类初始化多个Thread实例),适合于多个线程处理同一资源的情况,比如买票场景。

2.线程状态

线程的各个状态以及之间的转换条件和路径如下图所示:

初始状态:Thread实例初始化完成。

可运行状态:调用线程实例的start方法后,线程进入到可运行线程池中等待运行。

运行状态:处于可运行状态的线程获取到了CPU,进入到运行状态,开始执行线程逻辑。

阻塞状态:阻塞状态是因为处于正在运行状态的线程放弃CPU。一般阻塞状态分为3种:

等待阻塞:线程执行了对象的wait方法。此时线程会释放持有的锁,被放置进入JVM的等待池中。

同步阻塞:线程在尝试获取同步锁失败,被放置进入锁池中。

其他阻塞:调用sleep方法或者join方法,或者等待IO的时候。

死亡状态:线程执行完毕或者异常退出run方法。

3 常用函数

Thread.sleep() 函数:该函数会使对应的线程休眠指定毫秒的时间。休眠结束之后会进入到可运行状态。执行休眠的时候不会释放锁。

Thread.yield() 函数:该函数会使当前线程让出CPU,从运行状态变成可运行状态。之后所有处于可运行状态的线程竞争CPU。高优先级的线程会优先被OS调度执行。如果是相同优先级,则平等竞争,但是存在一种情况是,让出CPU的线程被OS再次选中执行。需要注意的是,yield函数不会导致线程转到阻塞状态。

thread.join() 函数:该方法是让当前线程等待其他线程终止。比如在A线程中调用线程B.join(),那么执行的效果就是线程A从运行状态变成阻塞状态,一直等待线程B执行完毕,线程A才会转为可运行状态。join方法一般用于主线程中需要使用子线程的执行结果的情况。

thread.setPriority() 函数:设置线程的执行优先级。java的线程包含10个优先级,用1-10表示,数字越大,优先级越高。默认的优先级是5.

/**

* The minimum priority that a thread can have.

*/

public final static int MIN_PRIORITY = 1;

/**

* The default priority that is assigned to a thread.

*/

public final static int NORM_PRIORITY = 5;

/**

* The maximum priority that a thread can have.

*/

public final static int MAX_PRIORITY = 10;

object.wait()函数:该函数在synchronized代码块中使用,作用是使当前线程进入到等待状态,并释放锁。直到其他线程调用该对象的notify或者notifyAll方法进行唤醒,被唤醒之后,需要首先获取到对象锁,才能执行逻辑。

object.notify()函数:唤醒在此对象监视器上等待的单个线程。如果所有线程都在此对象上等待,则会选择唤醒其中一个线程。notify()调用后,并不是马上就释放对象锁的,而是在相应的synchronized(){}语句块执行结束,自动释放锁后,JVM会在wait()对象锁的线程中随机选取一线程唤醒。

object.notifyAll()函数:功能与notify类似,不同点在于notifyAll函数唤醒对象监视器上等待的所有线程。

java多线程调用一个函数_Java 多线程(一)相关推荐

  1. java怎么调用存储函数_java中调用存储过程或存储函数的方法

    java中调用存储过程或存储函数的方法 1.调用存储过程:CallableStatement clstmt = null;try {clstmt = conn.prepareCall("{c ...

  2. java线程休眠sleep函数_Java多线程中sleep()方法详解及面试题

    一. Java线程生命周期(五个阶段) 新建状态就绪状态运行状态阻塞状态死亡状态 如图 二.sleep方法 API中的解释 static voidsleep(long millis) 使当前正在执行的 ...

  3. java异步多线程 判断线程状态_java多线程和异步回调

    在实际开发过程中遇到的多线程情况不多,但是在生产环境中多线程是最基本的情况,java面试时也会考到,所以看看多线程的知识还是很有必要的. Thread,Runnable,Callable,Future ...

  4. 多线程都调用一个函数,在这个函数中的一个局部变量什么情况会被修改

    对于一个局部变量应该是各线程独立的,一个线程不会改变另一个线程的临时变量. 多线程时, 几个线程间输出信息是交叉在一起的, 但你又没有区分是哪个线程输出的, 所以你自己就误认为是同一个线程输出的东西被 ...

  5. java 多进程写一个文件_java高并发多线程及多进程同时写入文件研究

    测试&思考: 环境:windows 七.linux centos 6.三.java8html java多线程同时写一个文件 java高并发环境下多线程同时写入一个文件时, 经过 FileLoc ...

  6. java 多线程使用线程池_Java多线程:如何开始使用线程

    java 多线程使用线程池 什么是线程? (What is a Thread?) A thread is a lightweight process. Any process can have mul ...

  7. java多线程下载源码_Java多线程文件分片下载实现的示例代码

    多线程下载介绍 多线程下载技术是很常见的一种下载方案,这种方式充分利用了多线程的优势,在同一时间段内通过多个线程发起下载请求,将需要下载的数据分割成多个部分,每一个线程只负责下载其中一个部分,然后将下 ...

  8. java 线程的基本概念_Java多线程——多线程的基本概念和使用

    一.进程和线程的基础知识 1.进程和线程的概念 进程:运行中的应用程序称为进程,拥有系统资源(cpu.内存) 线程:进程中的一段代码,一个进程中可以有多段代码.本身不拥有资源(共享所在进程的资源) 在 ...

  9. java多线程的实现方式_Java 多线程(一)——多线程的实现方式

    一.前言 Java 异常的处理方式与自定义异常 我们已经讲完了,从今天开始我们来学习多线程. 二.与多线程相关的概念 2.1.并发与并行并发:指两个或多个事件在同一个时间段内发生,具体如下图所示: 并 ...

最新文章

  1. SVG.js 文本绘制整理
  2. C语言学习之输出“魔方阵”。所谓魔方阵是指这样的方阵,它的每一行、每一列和对角线之和均相等。
  3. linux显示内存状态,Linux显示内存状态
  4. c++隐式类型转换存在的陷阱
  5. 解决火狐https问题 安全连接问题
  6. 魔板(信息学奥赛一本通-T1449)
  7. CANN 5.0硬核技术抢先看
  8. Juniper防火墙备份与恢复处理方法
  9. 基于springboot的健身管理系统
  10. ATV 开发 三 DRM技术简介
  11. FSM实例——按键消抖及状态检测
  12. 重心解模糊化matlab,谁能给我个用重心法的MATLAB模糊推理程序
  13. NotNorthwind-更新#1-您所有的Northwind都属于我们
  14. URAL1325-Dirt
  15. MINIGUI3.2 设置按钮前景色
  16. VMware与宿主机文件夹共享、虚拟机磁盘映射
  17. 大军师司马懿之军师联盟
  18. YOLO系列算法原理介绍
  19. 计算机本科生科研训练计划表,大学本科生科研训练计划(srtp)(10页)-原创力文档...
  20. 模糊测试软件测试_模糊测试

热门文章

  1. HTML DOM:replaceChild()和cloneNode()
  2. 洛谷 P1994 有机物燃烧
  3. MySQL 计算时间差
  4. ubuntu右键点击没有新建文档_如何复制百度文库豆丁文档
  5. 现在是时候认真看看医疗保健云安全了
  6. python之format函数
  7. 输入框input 修改placeholder样式
  8. 基于ThinkPHP6的极速后台开发框架
  9. java中validate_validate的使用
  10. [数据结构]八大排序算法总结