文章

线程创建方式

线程

  • 一个进程中若开辟多个线程,线程的运行由调度器控制,先后顺序不能人为干预。

  • 实现方式

    1. 继承 Thread类

      • 调用run方法,只有主线程一条路

      • 调用start方法,主线程和子线程并行交替执行

      • 1
        2
        3
        4
        5
        6
        7
        8
        9
        10
        11
        12
        13
        14
        15
        16
        17
        18
        19
        20
        21
        22
        23
        
        public class MyThread extends Thread{
               
            @Override
            public void run() {
                for (int i = 0; i < 20; i++) {
                    System.out.println("xixi");
                }
            }
               
            public static void main(String[] args) {
               
                MyThread myThread = new MyThread();
                //myThread.run();只有主线程一条路,先xixi后haha
                //开启线程,不一定立刻执行,由cpu调度
                myThread.start();//同时运行,xixi、haha交替
               
                //main线程
                for (int i = 0; i < 20; i++) {
                    System.out.println("haha");
                }
            }
               
        }
        
      • 导入common-io.jar下载图片

        1
        2
        3
        4
        5
        6
        7
        8
        9
        10
        11
        12
        13
        14
        15
        16
        17
        18
        19
        20
        21
        22
        23
        24
        25
        26
        27
        28
        29
        30
        31
        32
        33
        34
        35
        36
        37
        38
        39
        40
        41
        42
        43
        44
        45
        46
        47
        
        import org.apache.commons.io.FileUtils;
               
        import java.io.File;
        import java.io.IOException;
        import java.net.URL;
               
        public class MyThread2 extends Thread{
               
            private String url;
            private String name;
               
            public MyThread2(String url, String name){
                this.name = name;
                this.url = url;
            }
               
            @Override
            public void run() {
                WebDownloader webDownloader = new WebDownloader();
                webDownloader.downloader(url, name);
                System.out.println("下载了文件名为" + name);
               
            }
               
            public static void main(String[] args) {
                MyThread2 t1 = new MyThread2("https://ss0.bdstatic.com/70cFuHSh_Q1YnxGkpoWK1HF6hhy/it/u=3246675119,2528014287&fm=26&gp=0.jpg", "csgo1.jpg");
                MyThread2 t2 = new MyThread2("https://ss0.bdstatic.com/70cFuHSh_Q1YnxGkpoWK1HF6hhy/it/u=3246675119,2528014287&fm=26&gp=0.jpg", "csgo2.jpg");
                MyThread2 t3 = new MyThread2("https://ss0.bdstatic.com/70cFuHSh_Q1YnxGkpoWK1HF6hhy/it/u=3246675119,2528014287&fm=26&gp=0.jpg", "csgo3.jpg");
               
                t1.start();
                t2.start();
                t3.start();
               
            }
        }
               
        class WebDownloader{
            public void downloader(String url, String name){
                try {
                    FileUtils.copyURLToFile(new URL(url), new File(name));
                } catch (IOException e) {
                    e.printStackTrace();
                    System.out.println("downloader异常");
                } finally {
                }
            }
        }
        
    2. 实现Runnable接口

      • 推荐使用,避免单继承局限性,灵活方便,方便同一个对象被多个线程使用

      1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      11
      12
      13
      14
      15
      16
      17
      18
      19
      20
      21
      
        public class MyThread3 implements Runnable{
            @Override
            public void run() {
                for (int i = 0; i < 20; i++) {
                    System.out.println("xixi");
                }
            }
             
            public static void main(String[] args) {
             
                //创建实现runnable接口的类对象
                MyThread3 myThread3 = new MyThread3();
                //创建线程对象,通过线程对象启动线程,代理
                new Thread(myThread3).start();
             
             
                for (int i = 0; i < 20; i++) {
                    System.out.println("haha");
                }
            }
        }
      
      • 多线程同时操作一个对象

        1
        2
        3
        4
        5
        6
        7
        8
        9
        10
        11
        12
        13
        14
        15
        16
        17
        18
        19
        20
        21
        22
        23
        24
        25
        26
        27
        28
        29
        30
        31
        32
        33
        34
        35
        36
        37
        38
        39
        40
        41
        42
        43
        44
        45
        46
        
               
        public class Application {
            public static void main(String[] args) {
                MyThread4 myThread4 = new MyThread4();
                new Thread(myThread4, "ThreadA").start();
                new Thread(myThread4, "ThreadB").start();
                new Thread(myThread4, "ThreadC").start();
               
            }
        }
               
        class MyThread4 implements Runnable{
               
            private int ticketNumbs = 10;
               
            @Override
            public void run() {
                while (true){
                    if(ticketNumbs <= 0)
                        break;
               
                    // 模拟延时
                    try {
                        Thread.sleep(20);
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                    System.out.println(Thread.currentThread().getName() + "拿到了第" + ticketNumbs-- + "张票");
                }
            }
        }
        /**
         * ThreadA拿到了第9张票
         * ThreadB拿到了第8张票
         * ThreadC拿到了第10张票
         * ThreadB拿到了第7张票
         * ThreadA拿到了第7张票
         * ThreadC拿到了第6张票
         * ThreadA拿到了第5张票
         * ThreadB拿到了第4张票
         * ThreadC拿到了第3张票
         * ThreadA拿到了第2张票
         * ThreadB拿到了第1张票
         * ThreadA拿到了第0张票
         * ThreadC拿到了第0张票
         */
        
    3. 实现Callable接口

      • 可以定义返回值、可以抛出异常

      • 1
        2
        3
        4
        5
        6
        7
        8
        9
        10
        11
        12
        13
        14
        15
        16
        17
        18
        19
        20
        21
        22
        23
        24
        25
        26
        27
        28
        29
        30
        31
        32
        33
        34
        35
        36
        37
        38
        39
        40
        41
        42
        43
        44
        45
        46
        47
        48
        49
        50
        51
        52
        53
        54
        55
        56
        57
        58
        59
        60
        61
        
        import org.apache.commons.io.FileUtils;
               
        import java.io.File;
        import java.io.IOException;
        import java.net.URL;
        import java.util.concurrent.*;
               
        class MyCallable implements Callable<Boolean> {
               
            private String url;
            private String name;
               
            public MyCallable(String url, String name) {
                this.name = name;
                this.url = url;
            }
               
            @Override
            public Boolean call() {
                WebDownloader webDownloader = new WebDownloader();
                webDownloader.downloader(url, name);
                System.out.println("下载了文件名为" + name);
                return true;
            }
        }
               
        class WebDownloader {
            public void downloader(String url, String name) {
                try {
                    FileUtils.copyURLToFile(new URL(url), new File(name));
                } catch (IOException e) {
                    e.printStackTrace();
                    System.out.println("downloader异常");
                } finally {
                }
            }
        }
               
        public class Application {
            public static void main(String[] args) throws ExecutionException, InterruptedException {
                MyCallable t1 = new MyCallable("https://ss0.bdstatic.com/70cFuHSh_Q1YnxGkpoWK1HF6hhy/it/u=3246675119,2528014287&fm=26&gp=0.jpg", "csgo1.jpg");
                MyCallable t2 = new MyCallable("https://ss0.bdstatic.com/70cFuHSh_Q1YnxGkpoWK1HF6hhy/it/u=3246675119,2528014287&fm=26&gp=0.jpg", "csgo2.jpg");
                MyCallable t3 = new MyCallable("https://ss0.bdstatic.com/70cFuHSh_Q1YnxGkpoWK1HF6hhy/it/u=3246675119,2528014287&fm=26&gp=0.jpg", "csgo3.jpg");
               
                // 创建执行服务
                ExecutorService ser = Executors.newFixedThreadPool(3);
               
                // 提交执行
                Future<Boolean> r1 = ser.submit(t1);
                Future<Boolean> r2 = ser.submit(t2);
                Future<Boolean> r3 = ser.submit(t3);
               
                // 获取结果
                boolean rs1 = r1.get();
                boolean rs2 = r2.get();
                boolean rs3 = r3.get();
               
                // 关闭服务
                ser.shutdown();
            }
        }
        
本文由作者按照 CC BY 4.0 进行授权