Java练习——多线程

本文详细介绍了Java编程中的多线程应用,包括模拟多人过山洞的并发场景,使用synchronized控制线程同步,以及通过Runnable和Callable接口实现并发售票窗口。通过实例展示了如何创建和启动线程,以及注意事项
摘要由CSDN通过智能技术生成

Java练习——多线程

第一题

编写多线程应用程序,模拟多个人通过一次山洞的模拟.这个山洞每次只能通过一个人,每一个人通过山洞的时间为5秒,随机生成10个人,同时准备过此山洞,显示一下每次通过山洞人的姓名.

思路分析

  • 定义了一个类继承Thread。这意味着Test1是一个线程类。
  • 重写了run方法。这是线程的主要执行方法。当线程启动时,它会执行这个方法。
  • 在run方法中,使用synchronized关键字来同步代码块
  • 当线程进入同步代码块时,会先打印当前线程的名字和"正在过山洞…“。然后,线程会休眠5秒。休眠结束后,再打印当前线程的名字和"通过山洞!”。

完整代码

public class Test1 extends Thread{
    Lock lock = new Lock();
    @Override
    public void run(){
        synchronized (lock){
            System.out.println(Thread.currentThread().getName()+"正在过山洞...");
            try {
                TimeUnit.SECONDS.sleep(5);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            System.out.println(Thread.currentThread().getName()+"通过山洞!");
        }

    }

    public static void main(String[] args) {
        Test1 test1 = new Test1();
        new Thread(test1,"刘一").start();
        new Thread(test1,"陈二").start();
        new Thread(test1,"张三").start();
        new Thread(test1,"李四").start();
        new Thread(test1,"王五").start();
        new Thread(test1,"赵六").start();
        new Thread(test1,"孙七").start();
        new Thread(test1,"周八").start();
        new Thread(test1,"吴九").start();
        new Thread(test1,"郑十").start();
    }
}

运行结果

在这里插入图片描述

第二题

编写一个程序,模拟3个售票窗口,来卖10张票,要求一张票只能卖一次

思路分析

  • 定义一个类继承Thread,表示这是一个线程类;定义一个私有整数 ticket,表示当前剩余的票数,初始值为10。创建一个 Lock 对象
    lock,用于同步。
  • 线程执行逻辑 (run 方法):在循环内部,使用 synchronized (lock)
    来确保同一时间只有一个线程可以检查剩余票数和卖票。如果 ticket 大于0,表示还有票,那么线程会打印出卖出的票数和已售空的票数,然后ticket 减1。之后线程休眠1秒(模拟售票间隔),然后继续循环。
  • 创建了三个线程对象,分别命名为 “窗口1”、“窗口2” 和 “窗口3”,并启动它们。这意味着有三个窗口同时尝试售票。

完整代码

public class Test3 extends Thread {
    private int ticket = 10;
    Lock lock = new Lock();

    @Override
    public void run() {
        while (true){
            synchronized (lock) {
                if (ticket > 0) {
                    System.out.println(Thread.currentThread().getName() + "卖出了第" + ticket + "张票");
                    System.out.println("第" + ticket + "张票已售空!");
                    ticket--;
                }
            }
            try {
                TimeUnit.SECONDS.sleep(1);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }

    public static void main(String[] args) {
        Test3 test3 = new Test3();
        new Thread(test3, "窗口1").start();
        new Thread(test3, "窗口2").start();
        new Thread(test3, "窗口3").start();
    }
}

运行结果

在这里插入图片描述

总结

实现多线程有三种方式

  • 继承Thread类(用得不多)
public class MyThread extends Thread {
    @Override
    public void run() {
    System.out.println("执行了线程的run方法_");
    }
}

public class Test {
    public static void main(String[] args) {
    MyThread mta = new MyThread();
    MyThread mtb = new MyThread();
    
    mta.start();
    mtb.start();
    }
}
  • 实现Runnable接口:多线程类实现Runnable接口后,还是需要Thread类下的start()方法来启动线程
public class MyRunnable implements Runnable {
    @Override
    public void run() {
    System.out.println("我的线程...");
    }
}

public class Test {
    public static void main(String[] args) {
    MyRunnable mra = new MyRunnable();
    MyRunnable mrb = new MyRunnable();
    
    new Thread(mra).start();
    new Thread(mrb).start();     
    }
}

注意:

  • 启动多线程必须是通过线程类的对象来调用start()方法。不能直接调用run()方法,如果直接调用run()则仍然是单线程,没有启动多线程。
  • 线程不允许重复启动
  • 实现Callable接口

    • 创建Callable接口的实现类,并实现call()方法,该call()方法将作为线程执行体,并且有返回值。
    • 创建Callable实现类的实例,使用FutureTask类来包装Callable对象,该FutureTask对象封装了该Callable对象的call()方法的返回值。
    • 使用FutureTask对象作为Thread对象的target创建并启动新线程。
    • 调用FutureTask对象的get()方法来获得子线程执行结束后的返回值
  • 19
    点赞
  • 22
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值