多线程_10

本文深入探讨了Java中的并发与并行概念,解释了进程与线程的区别,并展示了线程的三种实现方式:继承Thread类、实现Runnable接口和使用Callable与FutureTask。通过实例代码详细阐述了线程同步、线程调度、锁机制(包括synchronized和ReentrantLock)、死锁以及生产者消费者模型。此外,还提到了阻塞队列在多线程通信中的应用。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

  • 并行:即同一时刻多条指令,在多个cpu上.同时进行
  • 并发:即同一时刻多条指令,在单个cpu交替执行
  • 进程:即正在运行的软件,具有独立性、动态性、并发性
  • 线程:进程中单个顺序控制流,简单来说是一条执行路径,即应用程序想做的事
  • 单线程:即一个进程只有一条执行路径
  • 多线程:即一个进程有多条执行路径
  • 实现线程的三种方式

public class MyThread extends Thread {

    @Override
    public void run() {
        //线程开启后执行的代码
        for (int i = 0; i < 100; i++) {
            //getname获取调用此代码的线程名称
            //因为是继承thread,可以直接获取当前正在执行线程对象,底层自动调用

            System.out.println(getName()+"第"+i+"次表白");
        }
    }
}

ublic class Test01 {
    public static void main(String[] args) {
        //多线程实现方式一,通过继承
        MyThread myThread = new MyThread();


        MyThread myThread1 = new MyThread();

        //这里的run方法仅仅代表创建对象后调用的方法,并没有开启线程
        //myThread.run();

        //start开启线程,有jvm虚拟机调用run方法

        //setname 设置方式一
        myThread.setName("蔡根花");
        myThread1.setName("大强");

        myThread.start();
        myThread1.start();

ublic class Test02 {
    public static void main(String[] args) {

        //多线程实现方式三

        //创建runnble实现类对象
        MyRunnble myRunnble = new MyRunnble();

        //创建Thread对象,并将Runnble实现类作为参数传进去
        Thread thread = new Thread(myRunnble);
        //即统一行代码利线程共同执行,且都完全执行
        //创建Thread对象,并将Runnble实现类作为参数传进去
        Thread thread1 = new Thread(myRunnble);

        thread.setName("你");
        thread1.setName("我");


        //开启线程
        thread.start();

        //开启线程
        thread1.start();



    }
}
public class MyRunnble implements Runnable{
    @Override
    public void run() {
        for (int i = 0; i < 100; i++) {

            try {
                //sleep休眠,即线程执行到此处时进行休眠时间
                Thread.sleep(1000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            //Thread.currentThread().getName(),即Thread.currentThread()先获取调用此线程对象,在用其对象调用getname方法获取名称
            System.out.println(Thread.currentThread().getName()+"多线程接口实现方式二"+i);
        }
    }
}


public class Test03 {
    public static void main(String[] args) throws ExecutionException, InterruptedException {
        //多线程实现方式三

        //创建callable实现类对象
        MyCallable myCallable = new MyCallable();

        //创建futuretask对象,泛型与之前保持一致,将callable实现类对象传进去
        //即意思为获取线程执行后的结果
        FutureTask<Boolean> futureTask = new FutureTask(myCallable);

        //创建Thread对象,并把futuretask对象传进去
        Thread thread = new Thread(futureTask);

        //设置线程名字
        thread.setName("李白");

        //调用getPriority方法获取当前线程的优先级
//        int priority = thread.getPriority();
//        System.out.println(priority);

        //设置当前线程优先级,相对来说抢占cpu几率更大
        //范围1--10之间
        thread.setPriority(9);

        //开启线程
        thread.start();



        //创建callable实现类对象
        MyCallable myCallable1 = new MyCallable();

        //创建futuretask对象,泛型与之前保持一致,将callable实现类对象传进去
        //即意思为获取线程执行后的结果
        FutureTask<Boolean> futureTask1 = new FutureTask(myCallable1);

        //创建Thread对象,并把futuretask对象传进去
        Thread thread1 = new Thread(futureTask1);

        thread1.setName("王维");

        //
//        int priority1 = thread1.getPriority();
//        System.out.println(priority1);

        thread1.setPriority(6);


        //开启线程

        thread1.start();



        //获取返回值
//        Boolean aBoolean = futureTask.get();
//        System.out.println(aBoolean);
    }
}


public class MyCallable implements Callable<Boolean> {
    //泛型跟想要返回结果保持一致
    @Override
    public Boolean call() throws Exception {

        try {
            Thread.sleep(1000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        for (int i = 0; i < 99; i++) {
            System.out.println(Thread.currentThread().getName()+"跟女孩表白"+i+"次");
        }
        //线程执行完后返回的结果
        return true;
    }
}
  • 线程常用方法:getname()获取线程名称 setname()设置线程名称 ,thread继承类能直接使用,但Runnble和callable接口实现类不能直接使用,需通过Thread.currentThread()先获取线程对象才能调用
  • sleep()线程休眠 thread类名直接调用
  • 线程调度:分时调度模型:即所有线程轮流使用cpu使用权,即平均分配 抢占式调度模型: 即相对优先级高的线程抢占的几率较大
  • getPriority() 获取当前线程的优先级 setPriority() 设置线程优先级(1-10之间)
  • 守护线程:为守护普通线程而存在 setDaemon()设置守护线程
  • 同步代码块:默认情况下是打开的,当有线程进去自动锁上

public class ticket implements Runnable {
    //卖票案例
    //定义一个变量用于记录票的总数
   private int sum = 100;

   private final Object object = new Object();

    @Override
    public void run() {

        //定义线程执行逻辑,即运行线程想做的事

            while (true){
                //同步代码块,this代表正在执行的线程
                synchronized (object){
                    if (sum<=0){
                        break;
                    }else {
                        try {
                            //即假设出票所用时间
                            Thread.sleep(100);
                        } catch (InterruptedException e) {
                            e.printStackTrace();
                        }
                        sum--;
                        System.out.println(Thread.currentThread().getName()+"正在卖票还剩下"+sum+"票");

                    }

            }
        }

    }
}

public class Test08 {
    public static void main(String[] args) {

        //创建实现类对象
        ticket ticket = new ticket();

        //创建thread对象
        Thread thread1 = new Thread(ticket);
        Thread thread2 = new Thread(ticket);

        thread1.setName("窗口一");
        thread2.setName("窗口二");

        thread1.start();
        thread2.start();

    }
}
  • 同步方法:即在方法返回值前面加synchronized

public class MyRunnble1 implements Runnable {
    //比较同步代码块和同步方法

    private static int sum = 100;
    @Override
    public void run() {

        while (true){
            if ("窗口一".equals(Thread.currentThread().getName())){
                //即当相等时则调用同步方法
                boolean synchronizedmethods = Synchronizedmethods();
                if (synchronizedmethods){
                    break;
                }


            }

            if ("窗口二".equals(Thread.currentThread().getName())){

                //同步静态方法
                //方法前用静态static修饰,共享数据用static修饰 ,任意对象变成实现类.class
                synchronized (MyRunnble1.class){
                    if (sum==0){
                        break;
                    }else {
                        try {
                            Thread.sleep(10);
                        } catch (InterruptedException e) {
                            e.printStackTrace();
                        }
                        sum--;
                        System.out.println(Thread.currentThread().getName()+"正在卖票还剩下"+sum+"张票");
                    }
                }

            }
        }
    }

    private static synchronized boolean Synchronizedmethods() {

        if (sum==0){
            return true;
        }else {
            //休眠10毫秒
            try {
                Thread.sleep(10);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            sum--;

            System.out.println(Thread.currentThread().getName()+"正在卖票还剩下"+sum+"张票");
            return false;
        }
    }
}

public class Test07 {
    public static void main(String[] args) {

        MyRunnble1 myRunnble1 = new MyRunnble1();

         Thread thread1 = new Thread(myRunnble1);
         Thread thread2 = new Thread(myRunnble1);

         thread1.setName("窗口一");
         thread2.setName("窗口二");

         thread1.start();
         thread2.start();
    }
}

  • lock锁:直接的显示怎么上锁、解锁
  • 创建lock接口实现类对象 ReentrantLock lock = new ReentrantLock(); unlock()释放锁 lock()获得锁
  • 死锁:即锁的嵌套造成
  • 生产者、消费者模式:

public class producers extends Thread {
    @Override
    public void run() {
        //生产者逻辑
        while (true){
            synchronized (table.object){
                if (table.sum==0){
                    break;
                }else {
                    if (!table.foot){
                        System.out.println(getName()+"正在生产食物");
                        table.foot = true; //生产好了食物
                        table.object.notifyAll();//唤醒等待的消费者
                    }else {
                        try {
                            //若食物还有则等待
                            table.object.wait();
                        } catch (InterruptedException e) {
                            e.printStackTrace();
                        }
                    }
                }
            }
        }
    }
}

public class consumers extends Thread{
    //继承thread类
    /*
    步骤
    1.whil(true)死循环包裹
    2.同步代码块包裹
    3.判断食物是否存在  , 存在的结果
    4.判断食物是否存在 ,不存在的结果
     */
    @Override
    public void run() {

        while (true){
            synchronized (table.object){
                //判断今天食物是否还有
                if (table.sum==0){
                    break;
                }else {
                    if (table.foot){
                        System.out.println(getName()+"正在吃");
                        table.foot =false;  //代表吃完了
                        table.object.notifyAll();//唤醒生产者继续生产
                        table.sum--; //生产后总量减一  从头开始的逻辑判断
                    }else {
                        //没有则等待
                        try {
                            table.object.wait();
                        } catch (InterruptedException e) {
                            e.printStackTrace();
                        }
                    }
                }
            }
        }

    }
}


public class Test02 {
    public static void main(String[] args) {
        producers producers = new producers();

        consumers consumers = new consumers();

        producers.setName("生产者");
        consumers.setName("消费者");

        producers.start();
        consumers.start();

    }
}


  • 阻塞队列

public class producer1 extends Thread {


    private final ArrayBlockingQueue<String> arr;

    public producer1(ArrayBlockingQueue<String> arr) {
        this.arr= arr;  //根据创建有参构造创建出成员变量,有参构造的出现即为了给成员变量赋值
    }

    @Override
    public void run() {


        while (true) {
            try {
                //输入数据
                arr.put("汉堡");
                System.out.println("厨师放了一个汉堡包");
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }

    }
}
public class consumer1 extends Thread {
    private final ArrayBlockingQueue<String> arr;

    public consumer1(ArrayBlockingQueue<String> arr) {
        this.arr= arr;
    }
    //消费者

    @Override
    public void run() {

        //阻塞对象调取方法
        while (true) {
            try {
                String take = arr.take();
                System.out.println("吃货正在吃"+take);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }

    }
}

public class Test04 {
    public static void main(String[] args) {

        ArrayBlockingQueue<String> arr = new ArrayBlockingQueue<>(1);

        //将阻塞对象传进去代表两个线程操作统一对象
        //创建线程对象一
        consumer1 consumer1 = new consumer1(arr);
        //创建线程对象二
        producer1 producer1 = new producer1(arr);


        consumer1.start();
        producer1.start();
    }
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值