线程同步

视频整理:

问题:通过多线程解决小朋友分苹果的问题:一共有5个苹果,2个小朋友同时拿苹果,每次拿一个,拿完为止

package org.jsoft.Thread;

public class ThreadApple implements Runnable{
    
    private int apple = 5;
    
    boolean getApple(){
        if(apple > 0 ){
            apple--;
            System.out.println(Thread.currentThread().getName() + "拿了一个苹果,还剩下" + apple +"个苹果");
            return true;
        }
        return false;
    }
    
    //线程体
    @Override
    public void run() {
        boolean flag = getApple();
        while(flag){
            flag = getApple();
        }
        System.out.println(Thread.currentThread().getName() + "线程结束了");
    }
    
    public static void main(String[] args) {
        ThreadApple thread = new ThreadApple();
        Thread t1 = new Thread(thread);
        t1.setName("第1个小朋友");
        Thread t2 = new Thread(thread);
        t2.setName("第2个小朋友");
        t1.start();
        t2.start();
    }
    
    /*控制台输出:第1个小朋友拿了一个苹果,还剩下3个苹果
    第2个小朋友拿了一个苹果,还剩下3个苹果
    第1个小朋友拿了一个苹果,还剩下2个苹果
    第2个小朋友拿了一个苹果,还剩下1个苹果
    第1个小朋友拿了一个苹果,还剩下0个苹果
    第2个小朋友线程结束了
    第1个小朋友线程结束了*/

   //但是这样存在线程安全问题
}
线程安全问题及解决:

package org.jsoft.Thread;

public class ThreaAppleSafeTest implements Runnable{
        
        /*线程安全问题:因为多个线程访问共享一个资源就容易发生线程安全问题,容易线程并发
         *那么此时就需要一个锁,就像坐火车一样,卫生间有人占用就要上锁,那么此时也就需要一个共同锁
         *(即两者共同的资源:ThreaAppleSafeTest),这样就解决了线程安全问题
         **/
        
        private int apple = 5;
        
        boolean getApple(){
            synchronized(this){//this指共同的资源
                if(apple > 0 ){
                    apple--;
                    //在上一个测试例子上加上Thread.sleep()
                    try {
                        Thread.sleep(1000);
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                    System.out.println(Thread.currentThread().getName() + "拿了一个苹果,还剩下" + apple +"个苹果");
                    return true;
                }
            }
            return false;
        }
        
        //线程体
        @Override
        public void run() {
            boolean flag = getApple();
            while(flag){
                flag = getApple();
            }
            System.out.println(Thread.currentThread().getName() + "线程结束了");
        }
        
        public static void main(String[] args) {
            ThreaAppleSafeTest thread = new ThreaAppleSafeTest();
            Thread t1 = new Thread(thread);
            t1.setName("第1个小朋友");
            Thread t2 = new Thread(thread);
            t2.setName("第2个小朋友");
            t1.start();
            t2.start();
        }
        
        /*
         * 
         * 出现线程安全问题时控制台输出:(用了Thread.sleep(1000),但是没有用同步锁的时候)
         * 第1个小朋友拿了一个苹果,还剩下3个苹果
               第2个小朋友拿了一个苹果,还剩下2个苹果
               第1个小朋友拿了一个苹果,还剩下1个苹果
               第2个小朋友拿了一个苹果,还剩下0个苹果
               第2个小朋友线程结束了
               第1个小朋友拿了一个苹果,还剩下0个苹果
               第1个小朋友线程结束了
         *当设置同步锁了以后就解决了:
         *  第1个小朋友拿了一个苹果,还剩下4个苹果
            第2个小朋友拿了一个苹果,还剩下3个苹果
            第1个小朋友拿了一个苹果,还剩下2个苹果
            第2个小朋友拿了一个苹果,还剩下1个苹果
            第2个小朋友拿了一个苹果,还剩下0个苹果
            第1个小朋友线程结束了
            第2个小朋友线程结束了(结果是不固定的,因为不一定是哪个线程抢占了CPU的资源)

         *    
        */


        
}
 

转载于:https://my.oschina.net/u/3686592/blog/2252612

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值