多线程详解04:多线程基础练习

多线程详解04:多线程基础练习

练习一:并行、并发概念

问题:请简单描述什么是并行,什么是并发?

答:

并发:一个CPU同一时间段内处理多个线程任务。并发的关键是你有处理多个任务的能力,不一定要同时。

并行:多个CPU同时处理多个线程任务,这些线程之间彼此互不影响。并行的关键是你有同时处理多个任务的能力。

所以它们最关键的点就是:是否是同时

练习二:进程概念、线程概念、线程与进程联系

问题:请描述什么是进程,什么是线程,进程与线程之间的关系,并举例说明。

答:

进程:可执行程序的一次执行过程,它是一个动态概念,是系统分配资源的单位,比如在Windows系统中,一个运行的xx.exe就是一个进程。

线程:

进程中的一个执行任务(控制单元),负责当前进程中程序的执行。一个进程至少有一个线程,一个进程可以运行多个线程,多个线程可共享数据。**线程是CPU调度和执行的单位。**例如微信程序中发起的每个聊天框都是一条线程。

练习三

问题:请描述Thread类中的*start()方法与run()*方法的区别。

答:

start()方法的作用是使线程启动, run()方法中写的是线程启动后的执行内容,且run()方法必须是public的访问权限,返回类型为void。*start()方法启动线程后自动调用run()*方法;

练习三 :多线程编码练习1

问题:

​ 请编写程序,分别打印主线程的名称和子线程的名称。

​ 要求使用两种方式实现:

​ 第一种方式:继承Thread类。

​ 第二种方法:实现Runnable接口。

答:

public class Demo05 {
    public static void main(String[] args) {
        String name1 = Thread.currentThread().getName();
        System.out.println(name1);

        //实现Thread类
        new Thread(){
            @Override
            public void run() {
                System.out.println(Thread.currentThread().getName());
            }
        }.start();

        //实现Runnable接口
        new Thread(
                ()->{
                    System.out.println(Thread.currentThread().getName());
                }
        ).start();
    }
}

输出结果:

main
Thread-0
Thread-1

练习四:多线程编码练习2:多线程匿名内部类练习

问题:

编写程序,创建两个线程对象,一根线程循环输出“播放背景音乐”,另一根线程循环输出“显示画面”,要求线程实现Runnable接口,且使用匿名内部类实现

答:

public class Demo06 {
    public static void main(String[] args) {
        new Thread(new Runnable() {
            @Override
            public void run() {
                for (int i = 0; i < 50; i++) {
                    System.out.println("播放背景音乐");
                }
            }
        }).start();

        new Thread(new Runnable() {
            @Override
            public void run() {
                for (int i = 0; i < 50; i++) {
                    System.out.println("显示画面");
                }
            }
        }).start();
    }
}

练习五:多线程编码练习3

问题:

创建多线程对象,开启多线程。在子线程中输出1-100之间的偶数,主线程输出1-100之间的奇数。

答:

public class Demo07 {
    public static void main(String[] args) {
        for (int i = 1; i < 101; i++) {
            if (i%2!=0){
                System.out.println(i);
            }
        }

        new Thread(
                ()-> {
                    for (int i = 1; i < 101; i++) {
            if (i%2!=0){
                System.out.println(i);
            }
        }
                }
        ).start();
    }
}

练习六:多线程编码练习4

问题:

​ 请按要求编写多线程应用程序,模拟多个人通过一个山洞:

​ 1.这个山洞每次只能通过一个人,每个人通过山洞的时间为5秒;

2.随机生成10个人,同时准备过此山洞,并且定义一个变量用于记录通过隧道的人数。

显示每次通过山洞人的姓名,和通过顺序;

答:

问题分析:

  1. sleep(5000)
  2. 10条线程
  3. 同步代码块解决线程安全问题:如多个线程同时卖票时可能相同号码的票被卖了多次
    synchronized(锁对象) {
    原子操作的代码;【有可能出现线程安全问题的代码】
    }
  4. 锁对象可以是任何引用类型的对象(如 Object类的对象obj)
  5. 锁对象一旦被确定下来要保证唯一性
  6. 优点和缺点
  7. 代码示例
  • 好处:解决了多线程的数据安全问题
  • 弊端:当线程很多时,因为每个线程都会去判断同步上的锁,这是很耗费资源的,无形中会降低程序
    的运行效率
public class Hello implements Runnable{
    @Override
    public void run(){
        synchronized(this){

            try{
                Thread.sleep(5000);
            }catch(InterruptedException e){
                e.printStackTrace();
            }
            System.out.println(Thread.currentThread().getName()+"通过了山洞");
        }
    }

    public static void main(String[] args){
        Hello p=new Hello();
        new Thread(p,"赵一").start();
        new Thread(p,"赵二").start();
        new Thread(p,"赵三").start();
        new Thread(p,"赵四").start();
        new Thread(p,"赵五").start();
        new Thread(p,"赵六").start();
        new Thread(p,"赵七").start();
        new Thread(p,"赵八").start();
        new Thread(p,"赵九").start();
        new Thread(p,"赵十").start();

    }
}

操作步骤描述

​ 1. 定义一个隧道类,实现Runnable接口:

​ 1.1 定义一个变量,用来记录通过隧道的人数;

​ 1.2 重写Runnable的run方法;

​ 1.3 定义一个同步方法,模拟每个人通过隧道需要5秒钟:

​ 1.3.1 子线程睡眠5秒钟,模拟每个人通过隧道需要5秒钟;

​ 1.3.2 改变通过的人次;

​ 1.3.3 打印线程名称及其通过隧道的顺序,模拟人通过隧道及其顺序;

​ 1.4 调用通过隧道的方法;

​ 2. 定义一个测试类:

​ 2.1 在main方法中创建一个隧道类对象;

​ 2.2 在main方法中,循环创建10个子线程对象,通过构造方法把隧道对象

​ 和线程名(作为人的姓名)传递进去,并开启子线程;

答:

public class Tunnel implements Runnable{
    int num = 0;
    @Override
    public void run() {
        synchronized (this){
            try {
                Thread.sleep(5000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            System.out.println(Thread.currentThread().getName()+"通过了隧道,此时共通过了"+ ++num+"个人");
        }
        }
}
public class Test {
    public static void main(String[] args) {
        Tunnel tunnel = new Tunnel();
        new Thread(tunnel,"赵1").start();
        new Thread(tunnel,"赵2").start();
        new Thread(tunnel,"赵3").start();
        new Thread(tunnel,"赵4").start();
        new Thread(tunnel,"赵5").start();
        new Thread(tunnel,"赵6").start();
        new Thread(tunnel,"赵7").start();
        new Thread(tunnel,"赵8").start();
        new Thread(tunnel,"赵9").start();
        new Thread(tunnel,"赵10").start();
    }
}
  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Clap of thunder

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

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

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

打赏作者

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

抵扣说明:

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

余额充值