java - day017 - 线程

  • 进程
    • 操作系统中, 并行执行的任务
  • 线程
    • 进程内部, 并行执行的任务
    • 进程包含线程
  • 线程的创建
    • 继承Thred
      • 定义 Thred 的子类
      • 重写 run() 方法
      • 在 run() 方法中的代码, 是与其他代码并行的代码
      • 线程启动后, 自动执行
      • package day1702_线程;
        
        public class Test1 {
            public static void main(String[] args) {
                
                T1 t1 = new T1();
                T1 t2 = new T1(); // 创建线程对象
                
                t1.start();       // 启动线程后, 自动执行
                t2.start();
                
                System.out.println("main");
                
            }
            
            static class T1 extends Thread{ // 继承线程
                @Override
                public void run() {
                    super.run();
                    
                    super.setName("thred1");// 设置线程名称
                    
                    super.getName();// 获取线程名
                    
                    String n = super.getName();
                    
                    for (int i = 0; i < 1000; i++) {
                        System.out.println(n+": "+i);
                    }
                    
                }
            }
        }

         


    • 实现 Runnable
      • 定义 Runnable 子类
      • 实现 run() 方法
      • 把 Runnable 对象, 放入Thred 线程对象启动
      • 线程启动后, 执行 Runnable 对象的 Run() 方法
      • package day1702_线程;
        
        public class Test2 {
            public static void main(String[] args) {
                
                R1 r1 = new R1();// 创建 R1 对象
                R1 r2 = new R1();
                
                Thread t1 = new Thread(r1); // 创建线程
                Thread t2 = new Thread(r2);
                
                t1.start(); // 执行线程
                t2.start();
                
            
            }
            
            static class R1 implements Runnable{
                @Override
                public void run() {
                    
                    // 获得 正在执行这行代码的线程对象
                    Thread t = Thread.currentThread();
                    
                    // 获得线程名
                    String n = t.getName();
                    for (int i = 0; i < 1000; i++) {
                        System.out.println(n+": "+i);
                    }
                }
            }
            
        }

         

  •  线程的状态
    • 新生
    • 可执行
    • 阻塞
    • 执行
    • 消亡   即run()结束
  • 线程的方法
    • Thread.currentThread(); // 获得正在执行这行代码的线程对象 
    • Thread.sleep(毫秒值)    // 当前线程暂停指定的毫秒时间  
    • iterrupt() 
      • 打断一个线程的暂停状态,  被打断的线程会出现异常
      • InterruptedException
    • package day1702_线程;
      
      import java.text.SimpleDateFormat;
      import java.util.Date;
      import java.util.Scanner;
      
      public class Test3 {
          public static void main(String[] args) {
              T1 t1 = new T1();
              t1.start();
              
              // main 线程 打断t1 线程的暂停状态
              System.out.println("按回车打断 t 线程");
              new Scanner(System.in).nextLine();
              
              t1.interrupt(); // 打断
          }
          
          static class T1 extends Thread{
              @Override
              public void run() {
                  // TODO Auto-generated method stub
                  super.run();
                  
                  SimpleDateFormat sdf = 
                          new SimpleDateFormat("HH:ss:mm");
                  
                  while (true) {
                      String s = sdf.format(new Date());
                      System.out.println(s);
                      
                      // 停一秒
                      try {
                          Thread.sleep(1000);
                      } catch (InterruptedException e) {
                          // TODO Auto-generated catch block
                          e.printStackTrace();
                          
                          System.out.println("谁TMD桶我");
                          break;
                          
                      }
                      
                  }
      
              }
          }
      }

       


    • join(); //当前线程,等待被调用的线程结束
    • package day1702_线程;
      
      public class Test4 {
          public static void main(String[] args) throws InterruptedException {
              // 1000万内的质数数量
              
              System.out.println(" 单线程");
              f1();
              System.out.println("五个线程");
              f2();
              
          }
          
          private static void f1() throws InterruptedException {
              long t = System.currentTimeMillis();
              
              T1 t1  = new T1(0,10000000);
              t1.start();
              
              // 让main 线程等待 t1 结束
              t1.join();
              int r = t1.count;
              
              
              t = System.currentTimeMillis() - t;
              System.out.println("执行时间: "+t);
              System.out.println("质数数量: "+r);
          }
          
          private static void f2() throws InterruptedException {
              // TODO Auto-generated method stub
              long t = System.currentTimeMillis();
              
              
              T1[] a = new T1[5];
              for (int i = 0; i < a.length; i++) {
                  a[i] = new T1(2000000*i,2000000*(i+1));
                  a[i].start();
              }
              
              int sum = 0;
              for (T1 t1 : a) {
                  t1.join();
                  sum+=t1.count;
              }
              
              
              t = System.currentTimeMillis() - t;
              System.out.println("执行时间: "+t);
              System.out.println("质数数量: "+sum);
          }
      
          
      
          static class T1 extends Thread{
              
              
              int from;
              int to;
              int count; //最终结果,质数的数量
              
              public T1(int from, int to) {
                  if (from <= 2) {
                      count = 1;
                      from = 3;
                  }
                  
                  this.from = from;
                  this.to = to;
              }
              
              
              @Override
              public void run() {
                  // TODO Auto-generated method stub
                  super.run();
              
                  for (int i = from; i < to; i++) {
                      if (isPrime(i)) {
                          count++;
                      }
                  }
                  
              }
      
              // 是否是质数
              private boolean isPrime(int i) {
                  double max = 1+Math.sqrt(i);
                  for (int j = 2; j < max; j++) {
                      if (i%j == 0) {
                          return false;
                      }
                  }
                  
                  return true;
              }
              
          }
      }

       

    • Thread.yield();
      • 当前线程放弃时间片, 让出 cpu 资源
    • getPriority(),  setPriority();
      • 优先级, 1到10, 默认5
    • setDaemon(true);
      • 后台线程,守护线程
      • 一般所有前台线程结束,虚拟机自动退出
      • package day1702_线程;
        
        import java.text.SimpleDateFormat;
        import java.util.Date;
        import java.util.Scanner;
        
        public class Test3 {
            public static void main(String[] args) {
                T1 t1 = new T1();
                t1.start();
            
                Thread t2 = new Thread() {
                    @Override
                    public void run() {
                        // TODO Auto-generated method stub
                        super.run();
                        
                        System.out.println("按回车打断 t 线程");
                        new Scanner(System.in).nextLine();
                        
                        t1.interrupt(); // 打断
                    }
                };
                
                t2.setDaemon(true); // 设置后台线程
                t2.start();
            }
            
            static class T1 extends Thread{
                @Override
                public void run() {
                    // TODO Auto-generated method stub
                    super.run();
                    
                    SimpleDateFormat sdf = 
                            new SimpleDateFormat("HH:ss:mm");
                    
                    for (int i = 0; i < 10; i++) {
                        String s = sdf.format(new Date());
                        System.out.println(s);
                        
                        // 停一秒
                        try {
                            Thread.sleep(1000);
                        } catch (InterruptedException e) {
                            // TODO Auto-generated catch block
                            e.printStackTrace();
                            
                            System.out.println("谁TMD桶我");
                            break;
                            
                        }
                    }
                        
                        
                    
        
                }
            }
        }

         

 

 

  • 多线程的数据访问冲突
    • 多个线程, 共享访问数据
    • 一个线程访问到修改的一半的数据,称为 脏数据
  •  线程同步 synchronized
    • 多个线程,步调一致的执行
    • 让多个线程, 争夺同一个对象的  同步锁
    • 谁抢到谁执行, 抢不到等待
    • 同步锁
      • 任何对象, 都有一个唯一的同步锁
    • synchronized
      • 遇到同步关键字, 要先抢到锁才能执行,否则等待
    • synchronized(对象){  }
      • 争夺指定对象的锁
    • package day1702_线程;
      
      import java.util.Arrays;
      
      public class Test5 {
          
          static char[] a = {'-','-','-','-'};
          static char v = '*';
          
          public static void main(String[] args) {
              new Thread() {
                  @Override
                  public void run() {
                      // TODO Auto-generated method stub
                      super.run();
                      
                      
                      while (true) {
                          
                          // 数组同步锁
                          synchronized (a) {
                              for (int i = 0; i < a.length; i++) {
                                  a[i] = v;
                              }
                              v = (v=='*'?'-':'*');
                          }
                          
                          
                      }
                  }
              }.start();
              
              new Thread() {
                  @Override
                  public void run() {
                      // TODO Auto-generated method stub
                      super.run();
                      
                      while (true) {
                          // 数组同步锁
                          synchronized (a) {
                              System.out.println(Arrays.toString(a));
                          }
              
                      }
                  }
              }.start();
          }
      }

       


    • synchronized void f() {  };
      • 抢当前对象的锁
    • package day1702_线程;
      
      public class Test6 {
          public static void main(String[] args) {
      
              R1 r1 = new R1();
              
              Thread t1 = new Thread(r1);
              t1.start();
              
              // main 线程死循环 ,检查 i 是否是奇数
              while (true) {
      
                  int i = r1.get();
                  if (i%2==1) {
                      System.out.println(i);
                      System.exit(0);// 关闭虚拟机
      
                  }
      
              }
          }
          
          static class R1 implements Runnable{
              
              static int i;
      
              synchronized public void add(){
                  i++;
                  i++;
              }
      
              synchronized public int get() {
                  return i;
              }
          
              @Override
              public void run() {
                  // TODO Auto-generated method stub
                  while (true) {
                      add();
                  }
              }
          }
      }

       


    • static synchronized void f() { };
      • 抢类的锁
    • package day1702_线程;
      
      public class Test6 {
          public static void main(String[] args) {
      
              R1 r1 = new R1();
              R1 r2 = new R1();
              
              Thread t1 = new Thread(r1);
              t1.start();
              
              Thread t2 = new Thread(r2);
              t2.start();
              
              // main 线程死循环 ,检查 i 是否是奇数
              while (true) {
      
                  int i = r2.get();
                  if (i%2==1) {
                      System.out.println(i);
                      System.exit(0);// 关闭虚拟机
      
                  }
      
              }
          }
          
          static class R1 implements Runnable{
              
              static int i;
      
              static synchronized public void add(){
                  i++;
                  i++;
              }
      
              static synchronized public int get() {
                  return i;
              }
          
              @Override
              public void run() {
                  // TODO Auto-generated method stub
                  while (true) {
                      add();
                  }
              }
          }
      }

       


 

posted @ 2019-08-18 14:51  Dingzhijie  阅读(189)  评论(0编辑  收藏  举报