【操作系统】实验——线程的控制(Java)

实验内容

 编写java程序,使用Thread 类或Runnable接口创建子线程,实现一个多窗口售票问题。A、B两个窗口同时对共享的10张票进行售卖。
要求:
1)说明java的线程创建语句;
2)分析问题中的临界资源,对比采用和不采用线程锁(synchronized) 实现互斥的共享时运行的结果的区别,并说明原因。3)每个线程在售票后输出格式为“时间+售卖出第i张票”,售票后通过sleep()函数使线程进入阻塞,并截图说明sleep()函数在不同参数下执行的变化。

基础知识简介

 线程(英语:thread)是操作系统能够进行运算调度的最小单位。它被包含在进程之中,是进程中的实际运作单位。一条线程指的是进程中一个单一顺序的控制流,一个进程中可以并发多个线程,每条线程并行执行不同的任务。在Unix System V及SunOS中也被称为轻量进程(lightweight processes),但轻量进程更多指内核线程(kernel thread),而把用户线程(user thread)称为线程。
 synchronized的使用很简单,可以用它来修饰实例方法和静态方法,也可以用来修饰代码块。synchronized是一个对象锁,也就是它锁的是一个对象。用它锁住对象,避免多个线程对临界资源这个对象进行访问,防止发生并发带来的冲突问题。
希望更深入学习synchronized关键字的,可以参考以下链接:Java中Synchronized的用法(简单介绍)

实验过程

 使用两个窗口对票进行售卖,其中一个使用线程锁,一个不使用,对比观察输出结果。
 首先线程创建语句创建Thread对象,随后TicketSeller类使用Runnable接口,重写方法run。采用线程锁和不采用线程锁的输出结果不同,采用线程锁后正常对票进行售卖,不采用线程锁则会发生票重复售出的情况。
 发生原因为:当一个线程访问一个被synchronized关键字保护的代码块或方法时,会尝试获取该对象的锁,如果锁没有被其他线程占用,则该线程获取锁并执行代码;如果锁已经被其他线程占用,则该线程会被阻塞,直到其他线程释放锁,以此保护临界资源被多个线程读取。
 当sleep(1000)时,线程会在售票后阻塞1秒钟,然后继续执行;当sleep(5000)时,线程会在售票后阻塞5秒钟,然后继续执行。

代码

public class TicketSeller implements Runnable{
    private int ticket = 10;
    @Override
    public void run() {
        while (ticket > 0) {
            synchronized (this) {//线程锁
                if (ticket > 0) {//对票进行售卖
                    System.out.println(System.currentTimeMillis() + " 售卖出第" + (11 - ticket) + "张票");//展示售票时间和售卖的票数
                    ticket--;
                }
            }
            try {
                Thread.sleep(50); // 售票后进入阻塞
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }
    public static void main(String[] args) {
        TicketSeller seller = new TicketSeller();
        Thread t1 = new Thread(seller);
        Thread t2 = new Thread(seller);
        t1.start();
        t2.start();
    }
}

public class TicketSeller2 implements Runnable {
    private volatile int ticket = 10;
    @Override
    public void run() {
        while (ticket > 0) {
            if(ticket > 0){
                System.out.println(System.currentTimeMillis() + " 售卖出第" + (11 - ticket) + "张票");
                ticket --;
            }else{
                break;
            }
            try {
                Thread.sleep(50); // 售票后进入阻塞
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }

    public static void main(String[] args) {
        TicketSeller2 seller = new TicketSeller2();
        Thread t1 = new Thread(seller);
        Thread t2 = new Thread(seller);
        t1.start();
        t2.start();
    }
}

谢谢各位的阅读

  • 8
    点赞
  • 12
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值