java并发基础多线程学习(5)-多线程间共享变量

package com.nuanshui.frms.native1.thread;

/**
 * @author liyy
 * @description:多线程通信
 * @date 2019-03-27 19:58
 * @program frms-parent
 */
public class MultiThreadShareData {

    public static void main(String[] args){
        //100票  10个售票员(票务对象)对10个窗口(线程)去卖票  1 99 1 99 1 99
        //100票  1个售票员去(票务对象)对10个窗口(线程)去卖票 1 99
        ShareTicket shareTicket = new ShareTicket();
        /*ShareTicket shareTicket = new ShareTicket();
        for(int i=0;i<10;i++){
           new Thread(shareTicket).start();
        }*/

        for(int i=0;i<120;i++){
            new Thread(new Runnable() {
                @Override
                public void run() {
                    shareTicket.sell();
                }
            }).start();
        }


    }

    /*static class ShareTicket implements Runnable{

        public  int ticketTotal = 100;
        @Override
        public void run() {
            if(ticketTotal>0){
                System.out.println(Thread.currentThread().getName()+"消费一张票");
                ticketTotal -- ;
                System.out.println("剩余票数:"+ticketTotal);
            }
        }
    }*/

    static class ShareTicket{
        public  int ticketTotal = 100;
        public void sell() {
            synchronized (this){
                if(ticketTotal>0){
                    System.out.println(Thread.currentThread().getName()+"消费一张票");
                    ticketTotal -- ;
                    System.out.println("剩余票数:"+ticketTotal);
                }else{
                    System.out.println("票买完了");
                }
            }
        }
    }

}


简单的一个免票任务。new 120个线程同时去买票。多线程同时去操作共享变量总票数。分析一下。就是一个任务,交给多个线程同时去执行。要保证每个线程读取数据是正确的。那么就相当于一个售票员开了10个窗口卖100张票。每次只能操作一个窗口。synchronized (this)操作添加互斥锁。保证当前线程操作时其他线程都处于等待状态。

下面还有一个多任务。多线程执行操作某一个变量的场景:

package com.nuanshui.frms.native1.thread;

/**
 * @author liyy
 * @description:
 * @date 2019-03-27 20:24
 * @program frms-parent
 */
public class Business1 {

    public static int data = 0;
    //设计四个线程,其中两个线程每次对 data 增加 1,另外两个线程每次对 data 减少 1。
    //负责对data增1
    public synchronized void add(){
        System.out.println("before:"+Thread.currentThread().getName()+"对data增1前data是:"+data);
        data++;
        System.out.println("after:"+Thread.currentThread().getName()+"对data增1后data是:"+data);
    }


    public synchronized void minus(){
        System.out.println("before:"+Thread.currentThread().getName()+"对data减1前data是:"+data);
        data--;
        System.out.println("after:"+Thread.currentThread().getName()+"对data减1后data是:"+data);
    }

}
package com.nuanshui.frms.native1.thread;

/**
 * @author liyy
 * @description:
 * @date 2019-03-27 20:30
 * @program frms-parent
 */
public class MultiThreadShareData1 {

    public static void main(String[] args){

        Business1 business1 = new Business1();
        for(int i=0;i<2;i++){
            new Thread(new Runnable() {
                @Override
                public void run() {
                    business1.add();
                }
            }).start();
        }

        for(int i=0;i<2;i++){
            new Thread(new Runnable() {
                @Override
                public void run() {
                    business1.minus();
                }
            }).start();
        }

    }
}

问题关键是锁对象必须是一样的。这样才能保证每次线程都能拿到同一把锁。并让其他线程等待。

总结如下:

多个线程之间共享数据主要关注两点就行:一是什么任务?几个任务?二是几个线程?记住 一点:几个任务和几个线程是没有关系的!100 个线程可以执行一个任务,也可以执行 2 个任务,3 个任务……

如果只有一个任务,那说明多个线程执行一个任务,我们只要实现一个 Runnable 接口,把公共 data 放进 Runnable,把任务放进去 run() 中即可(任务注意要同步),然后开启 N 个线程去执行这个任务即可;如果有 M 个任务,那我们新建一个专门执行任务的类,把公共的 data 放进类中,把任务作为类中的同步方法即可,然后开启 N 个线程,每个线程中扔一个 Runnable,按照要求执行任务类中的方法即可。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值