1.并发和并行

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

image.png

2.线程与进程

  • 进程:是指一个内存中运行的应用程序,每个进程都有一个独立的内存空间,一个应用程序可以同时运行多个进程;进程也是程序的一次执行过程,是系统运行程序的基本单位;系统运行同一个程序即使一个进程从创建、运行到消亡的过程
  • 线程:线程是进程中的一个执行单元,负责当前进程中程序的执行,一个进程中至少有一个线程。一个进程中是可以有多个线程的,这个应用程序也可以称之为多线程程序。

简而言之:一个程序运行后至少有一个进程,一个进程中可以包含多个线程

2.1进程

ROM:Read-Only Memory

只读内存简称,只读存储器—-硬盘

RAM:Random Access Memory

随机存取存储器—-内存

image.png

2.2线程

image.png

3.线程调度

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

      4.多线程原理

      4.1随机打印原理

      image.png

4.2内存图解

image.png

5.Thread类

5.1获取和设置线程名

Thread类中设置和获取线程名称的方法

  • void setName(String name):将此线程的名称更改为等于参数name
  • String getName():返回此线程的名称
  • 通过构造方法也可以设置线程名称

如何获取main()方法所在的线程名称?

  • public static Thread currentThread():返回对当前正在执行的线程对象的引用 ```java package com.study_01.getName;

public class MyThread extends Thread{ public MyThread() { }

  1. public MyThread(String name) {
  2. // 把线程名称给父类,让父类给他取名字
  3. super(name);
  4. }
  5. @Override
  6. public void run() {
  7. // 获取线程名称
  8. System.out.println(Thread.currentThread().getName());
  9. }

}

  1. ```java
  2. package com.study_01.getName;
  3. public class Demo01GetThreadName {
  4. public static void main(String[] args) {
  5. // 开启多线程
  6. MyThread mt = new MyThread();
  7. mt.setName("子线程1");
  8. mt.start();
  9. // 开启多线程
  10. new MyThread("子线程2").start();
  11. System.out.println("main:"+Thread.currentThread().getName());
  12. }
  13. }
  14. /*
  15. 子线程1
  16. 子线程2
  17. main:main
  18. */

5.2 线程控制

image.png

  1. public class Demo01Sleep {
  2. public static void main(String[] args) {
  3. for (int i = 0; i < 20; i++) {
  4. System.out.println(i);
  5. try {
  6. Thread.sleep(1000);
  7. } catch (InterruptedException e) {
  8. e.printStackTrace();
  9. }
  10. }
  11. }
  12. }

5.3通过Runable来实现多线程

  1. package com.study_04.Runable;
  2. public class RunableImpl implements Runnable {
  3. @Override
  4. public void run() {
  5. for (int i = 0; i < 20; i++) {
  6. System.out.println(Thread.currentThread().getName() + "-->" + i);
  7. }
  8. }
  9. }
  1. package com.study_04.Runable;
  2. public class Demo01Runable {
  3. public static void main(String[] args) {
  4. RunableImpl run = new RunableImpl();
  5. Thread t = new Thread(run);
  6. t.start();
  7. for (int i = 0; i < 20; i++) {
  8. System.out.println(Thread.currentThread().getName() + "-->" + i);
  9. }
  10. }
  11. }

5.4匿名内部类实现多线程

  1. package com.study_05.InnerClassThread;
  2. public class Demo01InnerClassThread {
  3. public static void main(String[] args) {
  4. // 线程的父类是Thread
  5. // new MyThread().start
  6. new Thread(){
  7. @Override
  8. public void run() {
  9. for (int i = 0; i < 20; i++) {
  10. System.out.println(Thread.currentThread().getName()+"-->"+i);
  11. }
  12. }
  13. }.start();
  14. // 线程的接口Runnable
  15. // Runnable r = new RunnableImpl(); // 多态
  16. Runnable r = new Runnable(){
  17. // 重写run方法设置线程任务
  18. @Override
  19. public void run() {
  20. for (int i = 0; i < 20; i++) {
  21. System.out.println(Thread.currentThread().getName()+"-->"+i);
  22. }
  23. }
  24. };
  25. new Thread(r).start();
  26. // 简化接口的方式
  27. new Thread(new Runnable(){
  28. @Override
  29. public void run() {
  30. for (int i = 0; i < 20; i++) {
  31. System.out.println(Thread.currentThread().getName()+"-->"+i);
  32. }
  33. }
  34. }).start();
  35. }
  36. }