黑马程序员技术交流社区

标题: [石家庄校区]Java多线程笔记 [打印本页]

作者: g207776411    时间: 2018-4-23 15:40
标题: [石家庄校区]Java多线程笔记
本帖最后由 小石姐姐 于 2018-4-26 14:16 编辑

Java多线程笔记


Day_11多线程
多线程是怎么实现的,线程是什么:
  
      进程:当前正在运行的程序,一个应用程序在内存中的执行区域
      线程:线程依赖于进程,他是进程中的执行控制单元,执行路
进程就是一个应用程序
同步:指的是单线程,一步一步的执行,一个执行完再执行下一个
异步:指的是多线程,同时进行
阻塞:指的是上一步成还没有执行完,程序就停留在这里
CPU在执行程序的随机性,所以多个线程同时运行,不一定哪一个线程在前
多线程两种实现的方式:                                                线程安全问题:                        多线程卖火车票练习:
​        假如一个线程执行static void sleep( )方法,就是让线程先睡一会,
​        假如不使用synchronized来给多线程上锁,则就会发生负数票数,异常
  
          /*
   * 12306卖火车票
   *
   */
  public class MyThreadTest {
      public static void main(String[] args) {
          // 创建Ticket
          // Ticket tick = new Ticket();
          Ticket2 tick = new Ticket2();
          // 创建多线程对象
          Thread t1 = new Thread(tick);
          Thread t2 = new Thread(tick);
          Thread t3 = new Thread(tick);
  ​
          // 修改线程名称
          t1.setName("一号窗口");
          t2.setName("二号窗口");
          t3.setName("三号窗口");
          // 打开线程
          t1.start();
          t2.start();
          t3.start();
  ​
      }
  }
  ​
  ​
  class Ticket implements Runnable {
      // 定义共享资源
      private Integer number = 100;
  ​
      @Override
      public synchronized void run() {
          while (true) {
              // 当票数大于零就继续卖票
              if (number > 0) {
                  try {
                      Thread.sleep(60);
                  } catch (InterruptedException e) {
                      // TODO Auto-generated catch block
                      // e.printStackTrace();
                      System.out.println("----------");
                  }
                  System.out.println(Thread.currentThread().getName() + "火车票剩余量:" + number);
                  number--;
              } else {
                  return;
              }
          }
      }
  ​
  }
  ​
  //
  class Ticket2 implements Runnable {
      // 定义共享资源
      private Integer number = 100;
  ​
      @Override
      public  void run() {
          while (true) {
              
              // 当票数大于零就继续卖票
              method();
              
          }
      }
  ​
  ​
  //这里我们抽取方法的时候
      private  synchronized void method() {
          if (number > 0) {
              try {
                  Thread.sleep(60);
              } catch (InterruptedException e) {
                  // TODO Auto-generated catch block
                  // e.printStackTrace();
                  System.out.println("----------");
              }
              System.out.println(Thread.currentThread().getName() + "卖掉了第" + number+"张票");
              number--;
          } else {
  //              System.out.println("票卖完了");
              return;
          }
      }
  ​
  }同步代码块
即使用关键字synchronized修饰的方法,一旦被一个线程访问,则整个方法全部锁住,其他线程则无法访问
在run方法中抽取的方法,并且被synchronized修饰,或者方法体内被        synchronized(锁){                         需要加锁的代码块               }
  
  ​
  private synchronized void printMehtod(int count, HashSet<Integer> array) {
              // 金额总和
              int sum = 0;
              System.out.print("在此次抽奖过程中," + Thread.currentThread().getName() + "总共产生了" + count + "个奖项,分别为:");
              for (Integer integer : array) {
                  sum += integer;
                  System.out.print(integer + ",");
              }
              System.out.println("最高奖项为" + Collections.max(array) + "元,总计额为" + sum + "元");
              //产生出最大奖项
              for (Integer integer : array) {
                  if (integer==800) {
                      System.out.println(Thread.currentThread().getName()+"产生最大奖,最大奖为:"+integer);
                  }
              }
          }
Synchronized的应用场景
​        在使用线程时,我们先要控制CPU的随机分配.,那我们将Run方法中的操作进行上锁,当一个线程执行完毕以后,后一个线程才会执行
​        这里我们要分清楚,线程共同的元素和非共有的元素
创建线程有两种方式
​        第一种方式:
        第二种方式:     自己创建一个实现Runnable接口的类
                        *         格式:                                
                                                类名     对象名=  new 类名();
                                        使用线程就创建几个Thread对象
                                                Thread  t1=new Thread(对象名)
                                                Thread  t1=new Thread(对象名)
Runnable接口出现的原因
多线程实现方式2:







欢迎光临 黑马程序员技术交流社区 (http://bbs.itheima.com/) 黑马程序员IT技术论坛 X3.2