Java总结--多线程与并发1

总览

  • Java中的进程和线程
    • 运行一个程序会产生一个进程,进程包含至少一个线程(主线程
    • 每个进程对应一个JVM实例,多个线程共享JVM里的堆
    • 主线程可以创建子线程,主线程原则上要后于子线程完成执行(各种关闭动作在主线程中执行

java线程(Thread)

  • Thread的start()run()

    • 调用start()会创建一个新的子进程并启动,run()只是Threa对象的普通方法调用
      在这里插入图片描述
      在这里插入图片描述
      在这里插入图片描述
      在这里插入图片描述
      注:由源码可得,start()会创建一个线程,然后去执行run()方法里的内容
    • Java线程创建关系图
      在这里插入图片描述
  • ThreadRunnable

    • Thread是类,Runnable是接口
    • Thread类实现了Runnable接口
    • Runnable只有一个抽象run()方法(Runnable不具有多线程的特性在这里插入图片描述
      在这里插入图片描述
  • java线程的创建

    1. 继承Thread类,并重写run()方法(线程中的逻辑在run()方法中实现
      public class MyThread extends Thread {
          private String name;
          public MyThread(String name){
              this.name = name;
          }
          @Override
          public void run(){
              for(int i = 0 ; i < 10 ; i ++){
                  System.out.println("Thread start : " + this.name + ",i= " + i);
              }
          }
      }
      
      public class ThreadDemo {
          public static void main(String[] args) {
              MyThread mt1 = new MyThread("Thread1");
              mt1.start();
          }
      }
      
    2. 实现Runnable接口
      原理:Thread带参构造函数中,可以传递Runnable,且调用Threadrun()方法会调用Runnable中的run()方法
      在这里插入图片描述
      在这里插入图片描述
      public class MyRunnable implements Runnable {
          private String name;
          public MyRunnable(String name){
              this.name = name;
          }
          @Override
          public void run(){
              for(int i = 0 ; i < 10 ; i ++){
                  System.out.println("Thread start : " + this.name + ",i= " + i);
              }
          }
      }
      
      public class RunnableDemo {
          public static void main(String[] args) throws InterruptedException {
              MyRunnable mr1 = new MyRunnable("Runnable1");
              Thread t1 = new Thread(mr1);
              t1.start();
          }
      }
      
    • 补充:给run()方法传参
      • 构造方法传参
      • 成员变量传参
      • 回调函数传参
  • java线程返回值的处理

    • 主线程等待法
      Thread.currentThread().sleep(500);
      
    • 使用Thread类的join()阻塞当前线程以等待子线程处理完毕
      public class CycleWait implements Runnable{
          private String value;
          public void run() {
              try {
                  Thread.currentThread().sleep(5000);
              } catch (InterruptedException e) {
                  e.printStackTrace();
              }
              value = "we have data now";
          }
      
          public static void main(String[] args) throws InterruptedException {
              CycleWait cw = new CycleWait();
              Thread t = new Thread(cw);
              t.start();
      //        while (cw.value == null){
      //            Thread.currentThread().sleep(100);
      //        }
              t.join();
              System.out.println("value : " + cw.value);
          }
      }
      
    • 通过Callable接口实现:通过FutureTask 或者线程池获取
      • FutureTask
        注:FutureTask实现了Runnable
        在这里插入图片描述
      • 判断Callable中的call方法是否执行完毕 在这里插入图片描述
      • call方法执行完毕,则返回,否则阻塞当前进程
        在这里插入图片描述
      • 带参get,增加了超时机制
        在这里插入图片描述
        //实现callable
        public class MyCallable implements Callable<String> {
            @Override
            public String call() throws Exception{
                String value="test";
                System.out.println("Ready to work");
                Thread.currentThread().sleep(5000);
                System.out.println("task done");
                return  value;
            }
        }
        //通过FutureTask完成等待
        public class FutureTaskDemo {
            public static void main(String[] args) throws ExecutionException, InterruptedException {
                FutureTask<String> task = new FutureTask<String>(new MyCallable());
                new Thread(task).start();
                if(!task.isDone()){
                    System.out.println("task has not finished, please wait!");
                }
                System.out.println("task return: " + task.get());
            }
        }
        
        //通过线程池等待
        public class ThreadPoolDemo {
            public static void main(String[] args) {
                ExecutorService newCachedThreadPool = Executors.newCachedThreadPool();
                Future<String> future = newCachedThreadPool.submit(new MyCallable());
                if(!future.isDone()){
                    System.out.println("task has not finished, please wait!");
                }
                try {
                    System.out.println(future.get());
                } catch (InterruptedException e) {
                    e.printStackTrace();
                } catch (ExecutionException e) {
                    e.printStackTrace();
                } finally {
                    newCachedThreadPool.shutdown();
                }
            }
        }
        
    • sleepwait方法
      • sleep
        • sleepThread类的方法
        • 可以在任何地方调用
        • sleep方法只会让出CPU,不会释放锁
      • wait
        • waitObject类中定义的方法
        • 只能在synchronized方法或synchronized块中使用
        • wait方法会让出CPU,也会释放已经占有的同步锁
      public class WaitSleepDemo {
          public static void main(String[] args) {
              final Object lock = new Object();
              new Thread(new Runnable() {
                  @Override
                  public void run() {
                      System.out.println("thread A is waiting to get lock");
                      synchronized (lock){
                          try {
                              System.out.println("thread A get lock");
                              Thread.sleep(20);
                              System.out.println("thread A do wait method");
                              lock.wait();
                              System.out.println("thread A is done");
                          } catch (InterruptedException e){
                              e.printStackTrace();
                          }
                      }
                  }
              }).start();
              try{
                  Thread.sleep(10);
              } catch (InterruptedException e){
                  e.printStackTrace();
              }
              new Thread(new Runnable() {
                  @Override
                  public void run() {
                      System.out.println("thread B is waiting to get lock");
                      synchronized (lock){
                          try {
                              System.out.println("thread B get lock");
                              System.out.println("thread B is sleeping 10 ms");
                              Thread.sleep(10);
                              lock.notifyAll();
                              Thread.yield();
                              Thread.sleep(2000);
                              System.out.println("thread B is done");
                          } catch (InterruptedException e){
                              e.printStackTrace();
                          }
                      }
                  }
              }).start();
      
          }
      }
      
    • 线程的中断
      • 调用interrupt()通知线程中断
        在这里插入图片描述
      • 线程中应该做的处理
        在这里插入图片描述
        public class InterruptDemo {
            public static void main(String[] args) throws InterruptedException {
                Runnable interruptTask = new Runnable() {
                    @Override
                    public void run() {
                        int i = 0;
                        try {
                            //在正常运行任务时,经常检查本线程的中断标志位,如果被设置了中断标志就自行停止线程
                            while (!Thread.currentThread().isInterrupted()) {
                                Thread.sleep(100); // 休眠100ms
                                i++;
                                System.out.println(Thread.currentThread().getName() + " (" + Thread.currentThread().getState() + ") loop " + i);
                            }
                        } catch (InterruptedException e) {
                            //在调用阻塞方法时正确处理InterruptedException异常。(例如,catch异常后就结束线程。)
                            System.out.println(Thread.currentThread().getName() + " (" + Thread.currentThread().getState() + ") catch InterruptedException.");
                        }
                    }
                };
                Thread t1 = new Thread(interruptTask, "t1");
                System.out.println(t1.getName() +" ("+t1.getState()+") is new.");
        
                t1.start();                      // 启动“线程t1”
                System.out.println(t1.getName() +" ("+t1.getState()+") is started.");
        
                // 主线程休眠300ms,然后主线程给t1发“中断”指令。
                Thread.sleep(300);
                t1.interrupt();
                System.out.println(t1.getName() +" ("+t1.getState()+") is interrupted.");
        
                // 主线程休眠300ms,然后查看t1的状态。
                Thread.sleep(300);
                System.out.println(t1.getName() +" ("+t1.getState()+") is interrupted now.");
            }
        }
        
    • 线程状态图
      在这里插入图片描述
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章