• 多线程


    day 08

    多线程

    并发与并行

    1. 并发:指两个或多个事件在同一个时间段内发生。

    2. 并行:指两个或多个事件在同一时刻发生(同时发生)。

    3. 当系统只有一个CPU时,线程会以某种顺序执行多个线程,我们把这种情况称之为 线程调度。

    线程与进程

    1. 进程:

      1. 是指一个内存中运行的应用程序;

      2. 每个进程都有一个独立的内存空间,一个应用程序可以同时运行多个进程;

      3. 进程也是程序的一次执行过程,是系统运行程序的基本单位;

      4. 系统运行一个程序即是一个进程从创建、运行到消亡的过程。

    2. 线程:

      1. 线程是进程中的一个执行单元,负责当前进程中程序的执行,一个进程中至少有一个线程。

      2. 一个进程中是可以有多个线程的,这个应用程序也可以称之为多线程程序。

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

    线程

    1. java.lang.Thread 类代表线程

    2. 自定义创建线程

      1. 方式一:继承Thread类

        1. 定义Thread类的子类,并重写该类的run()方法。

        2. run()方法的方法体就是线程需要完成的任务。

        3. 创建Thread子类的实例,即创建了线程对象。

        4. 调用线程对象的start()方法来启动该线程。

      2. 方式二:实现Runnable接口

        1. 创建一个类实现Runnable接口,并重写该类的run()方法。

        2. 创建Runnable实现类的实例,调用public Thread(Runnable target)方法,将实例作为参数target来创建Thread对象。

        3. 调用线程对象的start()方法来启动该线程。

      3. 方式三:匿名内部类

        Runnable r =new Runnable() {
                @Override
                public void run() {
                    
                }
            }
    3. 自定义线程名称

      public Thread(String name) :分配一个指定名字的新的线程对象。
    4. 获取线程名称

      public String getName() :获取当前线程名称。//方式一的获取方式
      public static Thread currentThread() :返回对当前正在执行的线程对象的引用。//方式二的获取方式

    线程安全

    线程安全

    线程安全问题都是由全局变量及静态变量引起的。若每个线程中对全局变量、静态变量只有读操作,而无写操作,一般来说,这个全局变量是线程安全的;若有多个线程同时执行写操作,一般都需要考虑线程同步,否则的话就可能影响线程安全。

    线程同步

    同步代码块

    • synchronized 关键字可以用于方法中的某个区块中,表示只对这个区块的资源实行互斥访问。

      synchronized(lock){
          需要同步操作的代码
      }

    同步方法

    • 使用synchronized修饰的方法,就叫做同步方法,保证A线程执行该方法的时候,其他线程只能在方法外等着。

      public synchronized void method(){
          可能会产生线程安全问题的代码
      }

    锁机制

    • java.util.concurrent.locks.Lock 机制提供了比synchronized代码块和synchronized方法更广泛的锁定操作。

    • Lock锁也称同步锁,加锁与释放锁方法化了,如下:

      public void lock() :加同步锁。

      public void unlock() :释放同步锁。

    • 创建Lock锁对象:Lock lock = new ReentrantLock();

    • 在需要同步的代码语句前加上同步锁方法,在结束的地方释放同步锁。

    线程状态

    NEW(新建)、Runnable(可运行)、Blocked(锁阻塞)、Waiting(无限等待)Timed Waiting(计时等待)、Teminated(被终止)

     案例

    • 银行取钱问题
      package ThreadDemo;
      //2.银行取钱模式
      //
      //        两个人AB通过一个账户去银行取钱,A在柜台取钱,B在ATM机取钱。
      //        假设账户总共有10000块, A每次从柜台取出100块,休息100毫秒,B每次从ATM机取出200块,休息200毫秒
      //        在每次取出钱之后,都展示一下用户取出了多少钱,银行账户还剩多少钱。
      //        如此循环往复,直到把账户中的钱取出,结束程序。
      
      public class BankTest {
          public static void main(String[] args) {
              Bank bank = new Bank();
              userA aa = new userA(bank);
              userB bb = new userB(bank);
              new Thread(aa, "用户A").start();
              new Thread(bb, "用户B").start();
          }
      }
      
      class Bank {
          private static int Money = 10000;
      
          public synchronized void A() {
              if (Money >= 100) {
                  Money -= 100;
                  System.out.println(Thread.currentThread().getName() + "用户取出了100元,银行账户还剩" + Money + "元");
                  notify();
              } else {
                  try {
                      wait();
                  } catch (InterruptedException e) {
                      e.printStackTrace();
                  }
              }
          }
          
          public synchronized void B() {
              if (Money >= 200) {
                  Money -= 200;
                  System.out.println(Thread.currentThread().getName() + "用户取出了200元,银行账户还剩" + Money + "元");
                  notify();
              } else {
                  try {
                      wait();
                  } catch (InterruptedException e) {
                      e.printStackTrace();
                  }
              }
          }
      }
      
      class userA extends Thread {
          private Bank bank;
      
          public userA(Bank bank) {
              this.bank = bank;
          }
      
          @Override
          public void run() {
              while (true) {
                  try {
                      Thread.sleep(100);
                  } catch (InterruptedException e) {
                      e.printStackTrace();
                  }
                  bank.A();
              }
          }
      }
      
      class userB extends Thread {
          private Bank bank;
      
          public userB(Bank bank) {
              this.bank = bank;
          }
      
          @Override
          public void run() {
              while (true) {
                  try {
                      Thread.sleep(200);
                  } catch (InterruptedException e) {
                      e.printStackTrace();
                  }
                  bank.B();
              }
          }
      }
      

        

  • 相关阅读:
    IEEE Bigger系列题解
    Codeforces Round #354 (Div. 2) E. The Last Fight Between Human and AI 数学
    Codeforces Round #354 (Div. 2) D. Theseus and labyrinth bfs
    Codeforces Round #354 (Div. 2) C. Vasya and String 二分
    Codeforces Round #354 (Div. 2) B. Pyramid of Glasses 模拟
    Codeforces Round #354 (Div. 2) A. Nicholas and Permutation 水题
    Codeforces Round #FF (Div. 1) B. DZY Loves Modification 优先队列
    Codeforces Round #FF (Div. 1) A. DZY Loves Sequences 动态规划
    2016 UESTC DP专题题解
    HDU 5701 中位数计数 暴力
  • 原文地址:https://www.cnblogs.com/---------zjh---------/p/13225855.html
Copyright © 2020-2023  润新知