Java 多线程编程(上)

版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接: https://blog.csdn.net/weixin_44510615/article/details/102617286

在 Java 中实现多线程有两种手段,一种是继承 Thread 类,另一种就是实现 Runnable 接口。
在这里插入图片描述

Java 提供了三种创建线程的方法:

  • 通过实现 Runnable 接口;
  • 通过继承 Thread 类本身;
  • 通过 Callable 和 Future 创建线程。

RunnableDemo.java

/**
 * @author: 毛利
 */
class RunnableDemo implements Runnable {
    private Thread t;
    private String threadName;

    RunnableDemo( String name) {
        //
        threadName = name;
        System.out.println("Creating " +  threadName );
    }

    public void run() {
        System.out.println("Running " +  threadName );
        try {
            for(int i = 4; i > 0; i--) {
                System.out.println("Thread: " + threadName + ", " + i);
                // 让线程睡眠一会0.05
                Thread.sleep(50);
            }
        }catch (InterruptedException e) {
            System.out.println("Thread " +  threadName + " interrupted.");
        }
        System.out.println("Thread " +  threadName + " exiting.");
    }

    public void start () {
        System.out.println("Starting " +  threadName );
        if (t == null) {
            t = new Thread (this, threadName);
            t.start ();
        }
    }
}

TestThread.java

/**
 * @author: 毛利
 */
public class TestThread {
    public static void main(String args[]) {
        RunnableDemo R1 = new RunnableDemo( "Thread-1");
        R1.start();

        RunnableDemo R2 = new RunnableDemo( "Thread-2");
        R2.start();
    }
}

实现 Runnable 接口

  • main入口函数创建线程
  • 线程执行的run方法,所以继承Runnable接口,改写run方法
public class CreateThreadAppMain {
    /*
    创建线程打印TEXT
     */
    
    // 定义变量TEXT不可变 
    private static final String TEXT = "私の名前はもうり、今日はJavaを勉強する\n" +
        "......";


    public static void main(String[] args) {
        // TODO 代码是被线程执行的,任何代码都可以通过Thread.currentThread()获取执行当前代码的线程
        // TODO 通过getName方法来获取线程的名字main
        System.out.println("程序开始,执行的线程名字叫做" + Thread.currentThread().getName());

        // TODO 如果改成2 线程-1先执行 线程-2慢执行 因为遍历需要时间
        for (int i = 1; i <= 1; i++) {
            // 学习创建线程的方法
            // TODO Runnable接口里的run是线程执行的方法,执行完毕,线程就结束了
            // TODO PrintStoryRunnable 需要改写run方法
            Thread thread = new Thread(new PrintStoryRunnable(TEXT, 200 * i), "我的线程-" + i);
            // TODO 创建好线程之后,如果要启动线程,必须调用start方法,注意不是run方法 但是执行的是run方法
            thread.start();
        }

        System.out.println("启动线程结束,名字叫做" + Thread.currentThread().getName());
    }
    // TODO 实现 Runnable 接口
    static class PrintStoryRunnable implements Runnable {
        private String text;
        private long interval;

        public PrintStoryRunnable(String text, long interval) {
            this.text = text;
            this.interval = interval;
        }
        // 改为run方法
        @Override
        public void run() {
            try {
                System.out.println("执行这段代码的线程名字叫做" + Thread.currentThread().getName());
                printSlowly(text, interval);
                System.out.println(Thread.currentThread().getName() + "执行结束");
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }

    public static void printSlowly(String text, long interval) throws InterruptedException {
        for (char ch : text.toCharArray()) {
            Thread.sleep(interval);
            System.out.print(ch);
        }
        System.out.println();
    }
}

守护线程

Java分为两种线程:用户线程和守护线程

如果我们不将一个线程以守护线程方式来运行,即使主线程已经执行完毕,程序也永远不会结束,可以尝试把上述将线程设为守护线程的那句注释掉,重新运行看看结果:

  • 就是main函数结束了,你这个线程就不要跑了,来保护你

只要添加thread.setDaemon(true);在补充优先级就ok了 thread.setPriority(Thread.MAX_PRIORITY);

public class DaemonThreadAppMain {

    private static final String TEXT = "私の名前はもうり、今日はJavaを勉強する\n" +
        "......";


    public static void main(String[] args) throws InterruptedException {
        System.out.println("程序开始,执行的线程名字叫做" + Thread.currentThread().getName());

        for (int i = 1; i <= 1; i++) {
            Thread thread = new Thread(new PrintStoryRunnable(TEXT, 200 * i), "我的线程-" + i);
            // TODO 可以在start之前设置线程为守护线程
            thread.setDaemon(true);
            // TODO 可以随时改变线程(和是不是守护线程没有关系)的优先级,但是作用不能保证
            thread.setPriority(Thread.MAX_PRIORITY);
            thread.start();
        }



        System.out.println("启动线程结束,名字叫做" + Thread.currentThread().getName());
    }

    static class PrintStoryRunnable implements Runnable {
        private String text;
        private long interval;

        public PrintStoryRunnable(String text, long interval) {
            this.text = text;
            this.interval = interval;
        }

        @Override
        public void run() {
            try {
                System.out.println("执行这段代码的线程名字叫做" + Thread.currentThread().getName());
                printSlowly(text, interval);
                System.out.println(Thread.currentThread().getName() + "执行结束");
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }


    public static void printSlowly(String text, long interval) throws InterruptedException {
        for (char ch : text.toCharArray()) {
            Thread.sleep(interval);
            System.out.print(ch);
        }
        System.out.println();
    }

}

在这里插入图片描述

执行就不会打印TEXT

猜你喜欢

转载自blog.csdn.net/weixin_44510615/article/details/102617286
今日推荐