zoukankan      html  css  js  c++  java
  • 多线程学习笔记

    多线程简介

    什么是线程?

    线程是进程中的一个执行场景,一个进程可以启动多个线程

    使用多线程可以提高CPU的使用率,不是提高执行速度。

    线程和线程之间共享堆内存和方法区,栈内存是独立的,每个线程有自己独立的栈

    进程包含多个线程。

    多线程的缺点

      • 设计复杂
        多线程中共享堆内存和方法区,因此里面的一些数据是可以共享的,在设计时要确保数据的准确性
      • 资源消耗增多
        栈内存是不共享的,如果启用多个线程的话会占用更多的内存

    多线程创建的三种方式之继承Thread类

    package ThreadTest;
    
    /**
     * 多线程练习继承Thread
     */
    public class ThreadTest01 {
        public static void main(String[] args) {
                new MyThread().start();
                new Thread(){
                    @Override
                    public void run() {
                        for (int i = 0; i < 1000; i++) {
                            System.out.println("线程1");
                        }
                    }
                }.start();
        }
    }
    
    class MyThread extends Thread{
        @Override
        public void run() {
            for (int i = 0; i < 1000; i++) {
                System.out.println("线程0");
            }
        }
    }

    多线程创建的三种方式之实现Runnable接口

    package ThreadTest;
    
    public class ThreadTest02 {
        public static void main(String[] args) {
            MyRunnable mr = new MyRunnable();
            new Thread(mr).start();
    
            new Thread(new Runnable(){
                @Override
                public void run() {
                    for (int i = 0; i < 100; i++) {
                        System.out.println("线程1");
                    }
                }
            }){
            }.start();
        }
    }
    
    class MyRunnable implements Runnable{
    
        @Override
        public void run() {
            for (int i = 0; i < 100; i++) {
                System.out.println("线程0");
            }
        }
    }

    多线程创建的三种方式之实现Callable接口

    import java.util.ArrayList;
    import java.util.concurrent.Callable;
    import java.util.concurrent.ExecutionException;
    import java.util.concurrent.ExecutorService;
    import java.util.concurrent.Executors;
    import java.util.concurrent.Future;
    
    /**
     * 多线程实现的第三种方法,实现Callable接口 优点: 可以获取返回值 可以抛出异常
     */
    
    //1.定义一个类实现Callable<V>接口
    class MyCallable implements Callable<Integer> {
    
        //睡眠时间
        private long second;
    
        //计算阶乘
        private int count;
    
        public MyCallable(int count, long second) {
            this.count = count;
            this.second = second;
        }
    
        // 2.重写call方法
        @Override
        public Integer call() throws Exception {
            // 3.将要执行的代码写在call方法中
            // 计算阶乘
            //让当前线程睡眠,单位是毫秒
            Thread.sleep(second);
            int sum = 1;
    
            if (count == 0) {
                sum = 0;
            } else {
                for (int i = 1; i <= count; i++) {
                    sum *= i;
                }
            }
    
            // 打印线程名称
            System.out.println(Thread.currentThread().getName() + "-----sum=" + sum);
    
            return sum;
        }
    
        public int getCount() {
            return count;
        }
    
        public void setCount(int count) {
            this.count = count;
        }
    
    }
    
    public class ThreadTest03 {
    
        public static void main(String[] args) throws InterruptedException, ExecutionException {
            //4.创建ExecutorService线程池
            ExecutorService exec = Executors.newCachedThreadPool();
    
            //5.创建存储Future对象的集合,用来存放ExecutorService的执行结果
            ArrayList<Future<Integer>> results = new ArrayList<Future<Integer>>();
    
            //6.开启2个线程,将返回的Future对象放入集合中
            for (int i = 0; i < 2; i++) {
                if (i == 0) {
                    //计算5的阶乘,睡眠10秒
                    results.add(exec.submit(new MyCallable(5, 10000)));
                } else {
                    //计算3的阶乘,睡眠i秒
                    results.add(exec.submit(new MyCallable(3, i)));
                }
            }
    
    
            for (Future<Integer> fs : results) {
                //7.判断线程是否执行结束,如果执行结束就将结果打印
                if (fs.isDone()) {
                    System.out.println("计算结果:" + fs.get());
                } else {
                    System.out.println(fs.toString() + "该线程还没有计算完毕,请耐心等待");
                }
            }
    
            //8.关闭线程池,不再接收新的线程,未执行完的线程不会被关闭
            exec.shutdown();
            System.out.println("main方法执行结束");
        }
    }

    匿名内部类的方式创建多线程

    package ThreadTest;
    
    import java.util.concurrent.*;
    
    public class 匿名内部测试方法 {
        public static void main(String[] args) throws ExecutionException, InterruptedException {
                 new Thread(){
                     @Override
                     public void run() {
                         for (int i = 0; i < 100; i++) {
                             System.out.println("Thread的线程");
                         }
                     }
                 }.start();
    
                 new Thread(
                         new Runnable() {
                             @Override
                             public void run() {
                                 for (int i = 0; i < 100; i++) {
                                     System.out.println("实现Runnable接口的线程");
                                 }
                             }
                         }
                 ){
    
                 }.start();
    
            ExecutorService es = Executors.newCachedThreadPool();  //创建线程池
            Future<Integer> submit = es.submit(new Callable<Integer>() {
                @Override
                public Integer call() throws Exception {
                    return 1024;
                }
            });
            System.out.println(submit.get());
        }
    }

    给线程命名和获取线程名

    package ThreadTest;
    
    import java.util.concurrent.*;
    
    public class 匿名内部测试方法 {
        public static void main(String[] args) throws ExecutionException, InterruptedException {
            new Thread("Thread线程") {
                @Override
                public void run() {
                    System.out.println(getName());
                }
            }.start();
    
            new Thread(
                    new Runnable() {
                        @Override
                        public void run() {
                            Thread.currentThread().setName("Runnable线程");
                            System.out.println(Thread.currentThread().getName());
                        }
                    }
            ) {
    
            }.start();
    
            ExecutorService es = Executors.newCachedThreadPool();  //创建线程池
            Future<Integer> submit = es.submit(new Callable<Integer>() {
                @Override
                public Integer call() throws Exception {
                    Thread.currentThread().setName("Callable线程");
                    System.out.println(Thread.currentThread().getName());
                    return 1024;
                }
            });
            System.out.println(submit.get());
        }
    }

    线程睡眠

    Thread中的sleep方法可以使当前线程睡眠,线程睡眠后,里面的任务不会执行,待睡眠时间过后会自动苏醒,从而继续执行任务。

    Thread中有两个重载的sleep方法
    sleep(long millis),指定睡眠毫秒数
    sleep(long millis, int nanos),第一个参数是毫秒,第二个参数是纳秒。

    package ThreadTest;
    
    /**
     * 使用Thread中的Sleep方法令线程睡眠
     */
    public class ThreadSleepTest01 {
        public static void main(String[] args) {
    //           new Thread(){
    //               @Override
    //               public void run() {
    //                   for (int i = 0; i < 10; i++) {
    //                       try {
    //                           Thread.sleep(1000);
    //                       } catch (InterruptedException e) {
    //                           e.printStackTrace();
    //                       }
    //                       System.out.println("睡眠线程!");
    //                   }
    //               }
    //           }.start();
    //
    //           new Thread(){
    //               @Override
    //               public void run() {
    //                   for (int i = 0; i < 10; i++) {
    //                       try {
    //                           Thread.sleep(1000);
    //                       } catch (InterruptedException e) {
    //                           e.printStackTrace();
    //                       }
    //                       System.out.println("1024");
    //                   }
    //               }
    //           }.start();
    
            new Thread() {
                @Override
                public void run() {
                    for (int i = 10; i > 0; i--) {
                        System.out.println(i);
                        try {
                            Thread.sleep(1000);
                        } catch (InterruptedException e) {
                            e.printStackTrace();
                        }
                    }
                }
            }.start();
        }
    }

    唤醒正在睡眠的线程

    package ThreadTest;
    
    /**
     * 使用Thread中的Sleep方法令线程睡眠
     */
    public class ThreadSleepTest01 {
        public static void main(String[] args) {
    
            Thread td = new Thread() {
                @Override
                public void run() {
                    try {
                        Thread.sleep(10000000);
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
    
                    for (int i = 0; i < 10; i++) {
                        System.out.println("sleep");
                    }
                }
            };
            td.start();
            td.interrupt();
        }
    }

    这里会打印出InterruptedException异常

     

     

  • 相关阅读:
    PowerDesigner通过SQL文件,反向生成模型
    跨域请求设置
    SSO单点登录与登出
    jwt使用
    git概念理解
    Slf4j MDC机制
    ASP.NET Core依赖注入最佳实践,提示&技巧
    EFCore数据库迁移命令整理
    RSA加密的使用
    CocoaPods 安装的第三方删除
  • 原文地址:https://www.cnblogs.com/xiaowangtongxue/p/10890138.html
Copyright © 2011-2022 走看看