多线程

1.创建线程的方式

1.1 继承Thread类
public class ThreadTest extends Thread{
    @Override
    public void run() {
        List<Integer> list = new ArrayList<>();
        for (int i = 0; i < 10000000; i ++) {
            list.add(i);
        }
        String name = Thread.currentThread().getName();
        System.out.println(name + ":" + list.size());
    }
}

执行

public static void threadRun() {
        ThreadTest threadTest = new ThreadTest();
        threadTest.start();
        ThreadTest threadTest2 = new ThreadTest();
        threadTest2.start();
        ThreadTest threadTest3 = new ThreadTest();
        threadTest3.start();
    }
1.2 继承Runnable接口
public class RunnableTest implements Runnable{
    @Override
    public void run() {
        List<Integer> list = new ArrayList<>();
        for (int i = 0; i < 10000000; i ++) {
            list.add(i);
        }
        String name = Thread.currentThread().getName();
        System.out.println(name + ":" + list.size());
    }
}

执行

public static void runnableRun() {
        RunnableTest runnableTest = new RunnableTest();
        Thread thread = new Thread(runnableTest);
        Thread thread2 = new Thread(runnableTest);
        Thread thread3 = new Thread(runnableTest);
        thread.start();
        thread2.start();
        thread3.start();
    }
1.3 使用CompletableFuthur

无返回值

CompletableFuture.runAsync(() -> {
            List<Integer> list = new ArrayList<>();
            for (int i = 0; i < 100000; i ++) {
                list.add(i);
            }
            String name = Thread.curren`在这里插入代码片`tThread().getName();
            System.out.println(name + ":" + list.size());
        });

有返回值

CompletableFuture<String> uCompletableFuture = CompletableFuture.supplyAsync(() -> {
            return "abc";
        });
        uCompletableFuture.get();

指定线程池

 CompletableFuture.runAsync(() -> {
            List<Integer> list = new ArrayList<>();
            for (int i = 0; i < 100000; i ++) {
                list.add(i);
            }
            String name = Thread.currentThread().getName();
            System.out.println(name + ":" + list.size());
        }, Executors.newFixedThreadPool(4));
1.4 其他方式

此外,我们还可以通过实现Callable接口 与Future配合使用,以及使用线程池来获取线程,这里就不详细说明了。以上三种方式足可以应付面试。

2.守护线程

所谓守护线程是指在程序运行的时候在后台提供一种通用服务的线程,当所有的非守护线程结束时,程序也就终止了,同时会杀死进程中的所有守护线程。反过来说,只要任何非守护线程还在运行,程序就不会终止。

public class DaemonTest extends Thread{
    @Override
    public void run() {
        System.out.println("守护线程执行");
        List<Integer> list = new ArrayList<>();
        for (int i = 0; i < 50; i ++) {
            list.add(i);
            System.out.println("守护线程" + ":" + list.size());
        }
		System.out.println("守护线程执行完毕!");
    }
}
public static void daemonRun() {

        ThreadTest threadTest = new ThreadTest();
        threadTest.start();
        DaemonTest daemonTest = new DaemonTest();
        daemonTest.setDaemon(true);
        daemonTest.start();

    }

我们利用上面的多线程例子,首先将计数器的次数都改为50,当一个正常的计数线程运行时,同时也运行一个守护线程,看看会发生什么

Thread-0:50
守护线程执行
守护线程:1
守护线程:2
守护线程:3

可以看到,守护线程并没有执行完,而是在正常计数器遍历完后关闭
再修改一下正常计数器,使次数改为100000,守护线程的次数仍然为50,看看会发生什么

守护线程执行
守护线程: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
守护线程执行完毕!
Thread-0:100000

可以看到,守护线程在正常线程结束前结束
由此可见,守护线程和正常线程会同时运行,守护线程可以先于正常线程结束,但是如果正常线程运行结束,那么jvm绝对不会等待守护线程结束。

3.控制线程的执行顺序

使用jion方法,让主线程等待子线程结束以后才能继续运行,因此保证了线程的顺序执行。
使用wait-notify/notifyAll方法,对线程进行等待和唤醒,从而控制线程的执行顺序

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值