Java实现主线程与子线程访问临界资源同步模拟

1.问题描述

        使用不同的方法完成主线程与子线程的同步,要求子线程先执行,在主线程中使用Thread类创建一个子线程,主线程创建后进入阻塞状态,直到子线程运行完毕后唤醒主线程。

2.代码实现

(2.1)方法1--(隐式)使用synchronized关键字

        为了保证主线程和子线程互斥的访问临界资源account除了使用对象锁机制实现,还可以采用显式Lock对象实现,线程互斥访问即:使同一时刻只能有一个线程读或写该临界资源,以实现临界区(即访问临界资源的那段代码)对临界资源的访问是互斥进行的。

        使用synchronized关键字,包括 设置synchronized语句块 方法和 设置synchronized方法 两种方式,如下所示。

public class ThreadSynchronization {
    class Bank{
        private int account = 100; //临界资源
        //获取account值
        public int getAccount(){
            return account;
        }
        //synchronized语句方法,保证线程互斥访问临界资源
        //该方法相当于“临界区”
        public synchronized void save(int money){
            account += money; //访问临界资源account
        }
        /*
            使用第2种方法:使用synchronized代码块
            //该方法相当于“临界区”
            public void save(int money){
                synchronized (this){
                    account += money; //访问临界资源account
                }
            }
        */
    //采用Runnable创建线程类
    class NewThread implements Runnable{
        private Bank bank;
        public NewThread(Bank bank){
            this.bank = bank;
        }
        @Override
        public void run() {   //重写 run()
            for (int i = 0; i < 10; i++) {
                bank.save(10);
                System.out.println(i + "账户余额为:" + bank.getAccount());
            }
        }
    }
    //建立线程
    public void useThread(){
        Bank bank = new Bank();//创建实现Runnable接口的实例
        NewThread new_Thread = new NewThread(bank);
        System.out.println("线程1");
        //线程1
        Thread thread1 = new Thread(new_Thread);
        thread1.start();//启动 
        System.out.println("线程2");
        //线程2
        Thread thread2 = new Thread(new_Thread);
        thread2.start();//启动
    }

    public static void main(String[] args) {
        ThreadSynchronization st = new ThreadSynchronization();//新建对象st
        st.useThread();//调用函数
    }

(2.2)方法2--(显式)使用Lock对象表示临界区

        为了保证主线程和子线程互斥的访问临界资源account除了使用对象锁机制实现,还可以采用显式Lock对象实现,线程互斥访问即:使同一时刻只能有一个线程读或写该临界资源,以实现临界区(即访问临界资源的那段代码)对临界资源的访问是互斥进行的。

        使用Lock对象实现线程互斥的访问临界资源需要通过“ import java.util.concurrent.locks.*; ” 命令对应类库,之后在对应临界资源处使用语句 Lock 对象名 = new ReentrantLock(); 创建Lock对象,之后使用 对象名.lock(); 加锁对象名.unlock();解锁(无论什么情况下均要执行,因此常放在异常处理的finally语句体中),具体如下所示。

public class ThreadSynchronization {
     class Bank{
        private int account = 100;
        //显示声明Lock对象
        private Lock lock = new ReentrantLock();
        //获取account值
        int getAccount(){
            return account;
        }

        //该方法相当于临界区
        public void save(int money){
            lock.lock();//加锁
            try{
                account += money;//访问临界资源account
            }finally{
                lock.unlock();//解锁
            }
        }
    }

    //采用Runnable创建线程类
    class NewThread implements Runnable{
        private Bank bank;
        public NewThread(Bank bank){
            this.bank = bank;
        }
        //重写 run()
        @Override
        public void run() {
            for (int i = 0; i < 10; i++) {
                bank.save(10);
                System.out.println(i + "账户余额为:" + bank.getAccount());
            }
        }
    }


    //建立线程,调用内部类
    public void useThread(){
        Bank bank = new Bank();//创建实现Runnable接口的实例
        NewThread new_Thread = new NewThread(bank);//传递bnak创建NewThread类实例
        System.out.println("线程1");
        //线程1
        Thread thread1 = new Thread(new_Thread);//传递new_Thread创建Thread类实例
        thread1.start();//启动
        System.out.println("线程2");
        //线程2
        Thread thread2 = new Thread(new_Thread);//传递new_Thread创建Thread类实例
        thread2.start();//启动
    }


    public static void main(String[] args) {
        ThreadSynchronization st = new ThreadSynchronization();
        st.useThread();//调用函数
    }

3.两种方法运行结果

(注意:Java线程调用 是 “抢占式” 的,因此 每次执行结果得到的线程顺序不同  是正常现象)

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

等日出看彩虹

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

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

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

打赏作者

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

抵扣说明:

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

余额充值