Java多线程1

线程:一个线程就是一个“执行流”,每个线程之间都可以按照顺序执行自己的代码,多个线程则同时运行着多份代码。

线程的出现:

  • “并发编程”成为了“刚需”:
  1. 单核的CPU发展遇到了瓶颈,单核的算力已不足以应对生产,此时就需要多核CPU,而并发编程更能充分利用多核CPU的资源。
  2. 有些任务场景需要“等待IO”,为了让等待IO的时间能够去做一些其他的工作,也需要用到并发编程。
  • 最然多进程可以实现“并发编程”,但是进程更加轻量化
  1. 创建线程比创建进程快;
  2. 销毁线程比销毁进程快;
  3. 调度线程比调度进程快。
  • 线程虽比进程更加轻量,但后续又出现了“线程池”和“协程”

进程和线程的区别:

  • 进程是包含线程的,每个进程中都有至少一个线程,即此进程的主线程。

  • 进程之间不共享内存空间,但是线程之间共享内存空间。

  • 进程是系统分配资源的最小单位,而线程是系统CPU调度的最小单位。

      线程是操作系统中的概念,操作系统内核实现了线程这样的机制,并且对用户层提供了一些API供用户使用。Java标准库中Thread类可以视为是对操作系统提供的API进行了进一步的抽象和封装。
    

线程的创建

  1. 继承Thread类
//继承Thread创建一个线程类
class  MyThread extends Thread{
    @Override
    public void run() {
        //具体的业务执行代码
        System.out.println("你好!");
    }
}
//创建MyThread的实例
MyThread myThread = new MyThread();
//启动线程
myThread.start();
  1. 实现Runnable接口
//实现Runnable接口
class MyThread2 implements Runnable{
    @Override
    public void run() {
        //具体业务执行代码
        Thread thread = Thread.currentThread();
        //输出线程名称
        System.out.println("线程名称:"+thread.getName());
    }
}
//创建Thread实例,并将Runnable对象作为参数
Thread thread = new Thread(new MyThread2());
//启动线程
thread.start();

以上两种方法:

  • 继承 Thread 类, 直接使用 this 就表示当前线程对象的引用。
  • 实现 Runnable 接口, this 表示的是 MyThread2 的引用. 需要使用 Thread.currentThread()。
  1. Runable其他变形
  • 使用匿名内部类创建子类对象
//使用匿名内部类创建Thread子类对象
Thread thread1 = new Thread() {
    @Override
    public void run() {
        System.out.println("变1");
   }
};
  • 使用匿名类创建 Runnable 子类对象
//使用匿名类创建 Runnable 子类对象
Thread thread2 = new Thread(new Runnable() {
    @Override
    public void run() {
        System.out.println("变2");
   }
});
  • 使用 lambda 表达式创建子类对象
// 使用 lambda 表达式创建 Thread 子类对象
Thread thread3 = new Thread(() -> {
    System.out.println("变3");
});
  1. 带返回值的Callable
  • 实现Callable新建线程
import java.util.Random;
import java.util.concurrent.Callable;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.FutureTask;

public class CallableDemo1 {
    public static void main(String[] args) throws ExecutionException, InterruptedException {
        //创建Callable实例
        MyCallable myCallable = new MyCallable();
        //用于接受Callable结果的对象
        FutureTask<Integer>  futureTask = new FutureTask<>(myCallable);
        //创建新线程
        Thread thread = new Thread(futureTask);
        //启动线程
        thread.start();
        //接受新线程执行的结果
        int result = futureTask.get();
        System.out.println(Thread.currentThread().getName()+"--新线程返回的结果为:"+result);
    }
}
class MyCallable implements Callable<Integer>{
    @Override
    public Integer call() throws Exception {
        //生成随机数范围0~9
        int randomNum = new Random().nextInt(10);
        System.out.println(Thread.currentThread().getName()+"--随机数:"+randomNum);
        return randomNum;
    }
}
  • 匿名Callable创建
import java.util.Random;
import java.util.concurrent.Callable;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.FutureTask;

public class CallableDemo2 {
    public static void main(String[] args) throws ExecutionException, InterruptedException {
        FutureTask<String >  futureTask = new FutureTask<>(new Callable<String>() {
            @Override
            public String call() throws Exception {
                //新线程执行的业务代码
                String[] arrays = new String[]{"Java","MySQL","Thread"};
                //随机返回一个字符串
                String result  = arrays[new Random().nextInt(3)];
                System.out.println(Thread.currentThread().getName()+
                        "--字符串:"+result);
                return result;
            }
        });
        //创建新线程
        Thread thread = new Thread(futureTask);
        //启动线程
        thread.start();
        String result = futureTask.get();
        System.out.println(Thread.currentThread().getName()+
                "--新线程的返回值:"+result);
    }
}

常见构造方法

方法说明
Thread()创建线程对象
Thread(Runnable target)使⽤ Runnable 对象创建线程对象
Thread(String name)创建线程对象,并命名
Thread(Runnable target, String name)使⽤ Runnable 对象创建线程对象,并命名
Thread(ThreadGroup group, Runnable target)线程可以被⽤来分组管理,分好的组即为线程组
Thread thread1 = new Thread();
Thread thread2 = new Thread(new MyRunnable());
Thread thread3 = new Thread("线程A");
Thread thread4 = new Thread(new MyRunnable(), "线程B");
  • 线程分组的使用
import java.util.Random;

public class ThreadDemo12 {
    public static void main(String[] args) {
        //1、创建一个线程分组
        ThreadGroup group = new ThreadGroup("thread_group");
        //2、定义一个公共的任务(线程的任务)
        Runnable runTask = new Runnable() {
            @Override
            public void run() {
                //业务执行代码
                //生成一个1-3秒的随机数
                int num = (new Random().nextInt(3)+1);
                try {
                    //执行num秒后结束
                    Thread.sleep(num*1000);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                Thread thread = Thread.currentThread();
                System.out.println(thread.getName()+"--任务用时:"+num+"s");
            }
        };
        //3、线程分组并分配业务
        Thread threadA = new Thread(group,runTask);
        Thread threadB = new Thread(group,runTask);
        Thread threadC = new Thread(group,runTask);
        //4、启动线程
        threadA.start();
        threadB.start();
        threadC.start();

        //所有全部结束后
        while (group.activeCount()>0){
        }
        System.out.println("业务完成");
    }
}
  • 0
    点赞
  • 0
    收藏
  • 打赏
    打赏
  • 0
    评论

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

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
©️2022 CSDN 皮肤主题:游动-白 设计师:我叫白小胖 返回首页
评论

打赏作者

_YQ97

你的鼓励将是我创作的最大动力

¥2 ¥4 ¥6 ¥10 ¥20
输入1-500的整数
余额支付 (余额:-- )
扫码支付
扫码支付:¥2
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值