Java中的线程
Posted ssc在路上
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Java中的线程相关的知识,希望对你有一定的参考价值。
一、概述进程与线程
进程:就是正在运行的程序。
进程是系统进行资源分配和调用的独立单位。每一个进程都有它自己的内存空间和系统资源。
意义:单进程的计算机只能做一件事情,而我们现在的计算机都可以做多件事情。举例:一边玩游戏(游戏进程),一边听音乐(音乐进程)。也就是说现在的计算机是支持多进程的,以在一个时间段内执行多个任务,并且,可以提交CPU的使用率。
线程:是程序的执行单元,执行路径。是程序使用CPU的最基本单位。
单线程:如果程序只有一条执行路径。
多线程:如果程序有多条执行路径。
意义:多线程的存在,不是提高程序的执行速度。其实是为了提高应用程序的使用率。程序的执行其实都是在抢CPU的资源,CPU的执行权。多个进程是在抢这个资源,而其中的某一个进程如果执行路径比较多,就会有更高的几率抢到CPU的执行权。是不敢保证哪一个线程能够在哪个时刻抢到,所以线程的执行有随机性。
二、线程的理解
1、线程的两种调度模型
(1)分时调度模型
所有线程轮流使用CPU的使用权,平均分配每个线程占用CPU的时间戳
(2)抢占式调度模型
优先让优先级高的线程使用CPU,若果线程的优先级相同,那么会随机选择一个,优先级搞的线程获取的CPU时间戳相对多一些
Java使用的是抢占式的调度模型
2、线程的生命周期
三。线程的创建方式
(1)继承Thread类。
步骤:
A:自定义类MyThread继承Thread类。
B:MyThread类里面重写run()?
C:创建对象
D:启动线程
1 /* 2 * 该类要重写run()方法,为什么呢? 3 * 不是类中的所有代码都需要被线程执行的。 4 * 而这个时候,为了区分哪些代码能够被线程执行,java提供了Thread类中的run()用来包含那些被线程执行的代码。 5 */ 6 public class MyThread extends Thread { 7 8 @Override 9 public void run() { 10 // 一般来说,被线程执行的代码肯定是比较耗时的。所以我们用循环改进 11 for (int x = 0; x < 200; x++) { 12 System.out.println(x); 13 } 14 } 15 } 16 17 public static void main(String[] args) { 18 // 面试题:run()和start()的区别? 19 // run():仅仅是封装被线程执行的代码,直接调用是普通方法 20 // start():首先启动了线程,然后再由jvm去调用该线程的run()方法。 21 // 创建两个线程对象 22 MyThread my1 = new MyThread(); 23 MyThread my2 = new MyThread(); 24 25 my1.start(); 26 my2.start(); 27 }
Thread类的一些方法:
如何获取线程对象的名称呢?
public final String getName():获取线程的名称。
如何设置线程对象的名称呢?
public final void setName(String name):设置线程的名称
针对不是Thread类的子类中如何获取线程对象名称呢?
public static Thread currentThread():返回当前正在执行的线程对象
Thread.currentThread().getName()
public final void setDaemon(boolean on):将该线程标记为守护线程或用户线程。
当正在运行的线程都是守护线程时,Java 虚拟机退出。 该方法必须在启动线程前调用。
public final void join():等待该线程终止。
public static void yield():暂停当前正在执行的线程对象,并执行其他线程。
public final void stop():让线程停止,过时了,但是还可以使用。
public void interrupt():中断线程。 把线程的状态终止,并抛出一个InterruptedException。
public static void sleep(long millis) 线程休眠
如何获取线程对象的优先级?
public final int getPriority():返回线程对象的优先级
如何设置线程对象的优先级呢?
public final void setPriority(int newPriority):更改线程的优先级。
注意:
线程默认优先级是5。
线程优先级的范围是:1-10。
线程优先级高仅仅表示线程获取的 CPU时间片的几率高,但是要在次数比较多,或者多次运行的时候才能看到比较好的效果。
(2)实现Runnable接口
步骤:
A:自定义类MyRunnable实现Runnable接口
B:重写run()方法
C:创建MyRunnable类的对象
D:创建Thread类的对象,并把C步骤的对象作为构造参数传递
1 public class MyRunnable implements Runnable { 2 3 @Override 4 public void run() { 5 for (int x = 0; x < 100; x++) { 6 // 由于实现接口的方式就不能直接使用Thread类的方法了,但是可以间接的使用 7 System.out.println(Thread.currentThread().getName() + ":" + x); 8 } 9 } 10 11 } 12 13 public static void main(String[] args) { 14 // 创建MyRunnable类的对象 15 MyRunnable my = new MyRunnable(); 16 17 // 创建Thread类的对象,并把C步骤的对象作为构造参数传递 18 // Thread(Runnable target) 19 // Thread t1 = new Thread(my); 20 // Thread t2 = new Thread(my); 21 // t1.setName("林青霞"); 22 // t2.setName("刘意"); 23 24 // Thread(Runnable target, String name) 25 Thread t1 = new Thread(my, "林青霞"); 26 Thread t2 = new Thread(my, "刘意"); 27 28 t1.start(); 29 t2.start(); 30 }
实现Runnable接口的好处:
(1)可以避免由于Java单继承带来的局限性
(2)适合多个相同的程序去处理同一个资源的情况,把线程同程序的代码,数据有效的分离,较好的提现了面向对象的设计思想
经典的值得思考的简单代码:(2019-05-27 21:48:00 继续写)
1 // 大体结构是这样的: 创建Thread对象:new Thread(创建Runnable对象:new Runnable(){ 执行Runnable的run()方法 }){ 执行Thread的run()方法 }.start(); 执行start方法 2 new Thread(new Runnable(){ 3 @Override 4 public void run() { 5 while (true) { 6 try { 7 Thread.sleep(500); 8 } catch (InterruptedException e) { 9 e.printStackTrace(); 10 } 11 System.out.println("Runnable:" + Thread.currentThread().getName()); 12 } 13 } 14 15 }){ 16 @Override 17 public void run() { 18 while (true) { 19 try { 20 Thread.sleep(500); 21 } catch (InterruptedException e) { 22 e.printStackTrace(); 23 } 24 System.out.println("Thread:" + Thread.currentThread().getName()); 25 } 26 }; 27 28 }.start();
之所以说这个例子比较经典,是因为你要搞懂这个到底在运行哪个run()方法,其实是在执行Thread类的run()方法,因为这个是重写Thread类的run()方法,只有在没有重写Thread类的run()方法的时候,才会去执行父类的run()方法,可以看下Thread类的源码:
1 private Runnable target; 2 3 @Override 4 public void run() { 5 if (target != null) { 6 target.run(); 7 } 8 }
以上是关于Java中的线程的主要内容,如果未能解决你的问题,请参考以下文章