Java中关于多线程的锁对象(同步代码块)使用的问题

例题

某公司组织年会,会议入场时有两个入口,在入场时每位员工都能获取一张双色球彩票,假设公司有100个员工,利用多线程模拟年会入场过程,并分别统计每个入口入场的人数,以及每个员工拿到的彩票的号码。线程运行后打印格式如下:
编号为: 2 的员工 从后门 入场! 拿到的双色球彩票号码是: [17, 24, 29, 30, 31, 32, 07]编号为: 1 的员工 从后门 入场! 拿到的双色球彩票号码是: [06, 11, 14, 22, 29, 32, 15]
…..
从后门入场的员工总共: 13 位员工
从前门入场的员工总共: 87 位员工

分析问题:

首先,题目明确给出入场以及出场以及入场两个线程,前门进入以及后门进入是同时进行的。

其次这里多个线程同时使用的的共享数据为人数number,两个线程都会对number的值进行修改。所以该线程存在安全问题,需要使用同步代码块把存在线程安全问题的代码锁起来

最后彩票可用Random生成随机数

代码实现

package 双色球彩票;

import java.util.Random;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;

//定义实现类PeopleThread实现接口Runnable接口并重写run()方法;
public class PeopleThread implements Runnable {
private int number = 1;
private Random ran = new Random();
private int qianmenpeople;
private int houmenpeople;
private String lottery;
private Lock lock = new ReentrantLock();

public void run() {
    while (number <= 100) {// 进行循环,人数编号从100-1;
        lock.lock();// 上锁
        for (int j = 0; j < 7; j++) {// 循环七次,获取七个随机的1-99的数字当作彩票号码
            int n = ran.nextInt(99) + 1;
            String str;
            if (n < 10) {
                str = "0" + n;//讲随机数转为String类型,若随机数生成为1-9的数,则改为01,02...
            } else {
                str = "" + n;//
            }
            if (j == 0) {//定义彩票输出格式
                lottery = "[" + str + " ";
            } else if (j == 6) {
                lottery = lottery + str + "]";
            } else {
                lottery = lottery + str + " ";
            }
        }
        System.out.println(
                "编号为:" + number + "_的员工  从" + Thread.currentThread().getName() + " 入场!" + "拿到的双色球彩票号码是:" + lottery);
        if (Thread.currentThread().getName().equals("前门")) {
            qianmenpeople++;//这里需要统计前门线程执行的次数
        }
        if (Thread.currentThread().getName().equals("后门")) {
            houmenpeople++;//这里需要统计后门线程执行的次数

        }
        number++;//线程执行结束后人数-1;
        lock.unlock();//释放锁
        try {
            Thread.sleep(100);//延时100毫秒
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }
    if (Thread.currentThread().getName().equals("前门")) {
        System.out.println("从" + Thread.currentThread().getName() + "入场的员工总共:" + qianmenpeople + " 位员工");
    }
    if (Thread.currentThread().getName().equals("后门")) {
        System.out.println("从" + Thread.currentThread().getName() + "入场的员工总共:" + houmenpeople + " 位员工");
    }
}

}

//定义测试类Test
public class Test {
public static void main(String[] args) {
PeopleThread pt = new PeopleThread();
new Thread(pt,”前门”).start();
new Thread(pt,”后门”).start();

}

}

输出结果:这里写图片描述

总结

遇到需要共同执行的线程时首先需判断线程是否存在安全问题,

存在安全问题:

1.是否为多线程环境
2.是否存在共享数据
3.是否存在多条语句共同执行

如何实现没有安全问题环境:

把多个语句操作共享数据的代码锁起来,让任意时刻只能有一个线程执行即可

  • 1
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值