20201019黄春跃

20201019黄春跃

知识点

并发和并行

并行:指两个或多个事件在同一时刻发生(同时执行)。
并发:指两个或多个事件在同一个时间段内发生(交替执行)。

进程和线程

进程

进程( Process )是指正在运行的程序,如 QQ ,是程序一次动态执行过程。它对应了从代码加载、执行
并执行完毕的一个完整过程,这个过程也是进程本身从产生、发展到消亡的过程。操作系统同时管理一
个计算机系统中的多个进程,让计算机系统中的多个进程轮流使用CPU资源,或者共享资源。

特点:
进程是系统运行的基本单位
每一个进程都有自己独立的空间、一组系统资源
每一个进程内部数据和状态都是完全独立的
每一个应用程序运行时都会产生一个进程

线程

线程是进程中执行运算的最小单位,一个进程在其执行过程中可以产生多个线程,而线程必须在某个
进程内执行。
线程是进程内部的一个执行单元,是可以完成一个独立任务的顺序控制流程。一个进程中至少有一个
线程。一个进程中是可以有多个线程的,这个应用程序也可以称之为多线程程序。

进程和线程的区别

进程:有独立的内存空间,进程中的数据存放空间(堆空间和栈空间)是独立的,至少有一个线
程。
线程:堆空间是共享的,栈空间是独立的,线程消耗的资源比进程小的多。

多线程和多进程的区别

本质的区别在于每个进程拥有自己的一套变量,而线程则是共享数据。线程之间共享数据是有风险的
(后边分析),然而共享变量使线程之间的通信比进程之间通信更有效、更容易。此外,在有的操作系
统中,与进程相比,线程更"轻量级",创建、撤销一个线程比启动新的进程开销要小的多。

线程调度

1. 分时调度
所有线程轮流使用 CPU 的使用权,平均分配每个线程占用 CPU 的时间。
2. 抢占式调度
优先让优先级高的线程使用 CPU,如果线程的优先级相同,那么会随机选择一个(线程随机性),
Java 使用的为抢占式调度。

创建线程类

每个程序至少自动拥有一个线程,称为主线程。当程序加载到内存时启动主线程。 java 程序中
public static void main(String[] args) 是主线程的入口,运行 java 程序时会执行这个方法。
创建一个新的执行线程有两种方法。 一个是将一个类声明为 Thread 的子类。 这个子类应该重写
Thread 类的方法 run 。 然后可以分配并启动子类的实例。

创建线程

继承 Thread 类,并重写 run() 方法。

package com.itlaobing.demo.thread;
public class MyThread extends Thread{
  //定义指定线程名称的构造方法
    public MyThread(String name) {
    //调用父类的String参数的构造方法,指定线程的名称
    super(name);
 }
  /**
  * 重写run方法,完成该线程执行的逻辑
  */
  @Override
  public void run() {
    for (int i = 0; i < 200; i++) {
      System.out.println(getName()+":正在执行!"+i);
   }
 }
}
@Test
public void testMyThread(){
  //创建自定义线程对象
  MyThread thread = new MyThread("myThread");
  //开启线程
  thread.start();
  //在主方法中执行for循环
  for (int i = 0; i < 200; i++){
    System.out.println("main()线程" + i);
 }
}

构造方法

public Thread() :分配一个新的线程对象。
public Thread(String name) :分配一个指定名字的新的线程对象。
public Thread(Runnable target) :分配一个带有指定目标新的线程对象。
public Thread(Runnable target,String name) :分配一个带有指定目标新的线程对象并指定
名字。

@Test
public void newInstance(){
  Thread thread = new Thread();
  Thread thread1 = new Thread("thread - 1a");
}
//线程可以拥有的最小优先级
public final static int MIN_PRIORITY = 1;
//分配给线程的默认优先级
public final static int NORM_PRIORITY = 5;
//线程可以拥有的最大优先级
public final static int MAX_PRIORITY = 10;
这几个属性用于表示线程的优先级

常用方法

Thread 类提供了大量控制和操作线程的方法,其中常用的有:
public static Thread currentThread() :返回对当前正在执行的线程对象的引用。
public void run() :如果这个线程是使用单独的 Runnable 运行对象构造的,则 Runnable 对象
的 run 方法; 否则,此方法不执行任何操作并返回。所有 Thread 的子类应该覆盖(重写)此方法
public synchronized void start() :线程开始执行; Java虚拟机调用此线程的 run 方法。结果
是两个线程同时运行:当前线程(从调用返回到 start 方法)和另一个线程(执行其 run 方
法), 多次调用此方法是不合法的。
public static native void sleep(long millis) :使当前正在执行的线程以指定的毫秒数暂
停(暂时停止执行),具体取决于系统定时器和调度程序的精度和准确性。 线程不会丢失任何
CPU的所有权。
public static void sleep(long millis, int nanos) :使当前正在执行的线程以指定的毫
秒数加上指定的纳秒数暂停(暂时停止执行)
public final String getName() :返回此线程的名称
public final synchronized void setName(String name) :将此线程的名称更改为等于参数
name
public final int getPriority() :返回此线程的优先级
public final void setPriority(int newPriority) :更改此线程的优先级,1~10之间
public final native boolean isAlive() :测试这个线程是否活着。 如果一个线程已经启动
并且尚未死亡,那么线程是活着的
public final void join() :等待线程死亡,等同于 join(0)
public final synchronized void join(long millis) :等待这个线程死亡的时间最多为
millis毫秒。 0的超时意味着永远等待
join 可以理解为当我们调用某个线程的这个方法时,这个方法会挂起调用线程,直到被调用
线程结束执行,调用线程才会继续执行。(让父线程等待子线程结束之后才能继续运行)
public void interrupt() :中断这个线程
public static boolean interrupted() :测试当前线程是否中断。 该方法可以清除线程的中断
状态(设置中断状态为 False ) 。 换句话说,如果这个方法被连续调用两次,那么第二个调用将返
回false(除非当前线程再次中断,在第一个调用已经清除其中断状态之后,在第二个调用之前已
经检查过)。
public boolean isInterrupted() :测试这个线程是否被中断。 线程的中断状态不受此方法的
影响。
public static native void yield() :导致当前执行线程处于让步状态。如果有其他可运行线
程具有至少与此线程同样高的优先级,那么这些线程接下来会被调度
public State getState() :返回此线程的状态,返回值是 Thread 的一个内部类,枚举类
State 。

线程状态可以是:

NEW 尚未启动的线程处于此状态。
RUNNABLE 在Java虚拟机中执行的线程(可以运行的线程)处于此状态。
BLOCKED 被阻塞等待监视器锁定的线程处于此状态。
WAITING 正在等待另一个线程执行特定动作的线程处于此状态。
TIMED_WAITING 正在等待另一个线程执行动作达到指定等待时间的线程处于此状态。
TERMINATED 已退出的线程处于此状态。

实现接口的方式创建

public class MyRunnable implements Runnable{
  @Override
  public void run() {
    for (int i = 0; i < 50; i++) {
      System.out.println(Thread.currentThread().getName()+" "+i);
   }
 }
}
@Test
public void testMyRunnable() throws InterruptedException {
  //创建线程任务对象
  MyRunnable runnable = new MyRunnable();
  //创建线程对象
  Thread thread = new Thread(runnable, "皇家一号线程");
  //启动线程
  thread.start();
  //线程休眠5S
  Thread.sleep(5000);
  for (int i = 0; i < 50; i++) {
    System.out.println("main线程 " + i);
 }
}

Thread和Runnable区别

实现 Runnable 接口比继承 Thread 类所具有的优势:

  1. 适合多个相同的程序代码的线程去共享同一个资源。
  2. 可以避免 java 中的单继承的局限性。
  3. 增加程序的健壮性,实现解耦操作,代码可以被多个线程共享,代码和线程独立。
  4. 实现了 Runable 接口的话,很容易的实现资源共享(一个实例多个线程运行)。
  5. 线程池只能放入实现 Runnable 或 Callable 类线程,不能直接放入继承 Thread 的类。

今日总结:

晚自习做了作业,写了试卷分析,复习了快排和前面集合的内容。

标签

评论

this is is footer