技术点集(面试)

  1. 怎么使用 ConcurrentHashMap 才能是线程安全的?

    package util;
    
    import java.util.Map;
    import java.util.concurrent.ConcurrentHashMap;
    
    public class test {
    	public static Map<String, Integer> chm = new ConcurrentHashMap<String, Integer>();
    
    	public static void main(String[] args) {
    		test.chm.put("test", 1);
    		tht t1 = new tht();
    		t1.start();
    		for (int i = 1; i < 1000; i++) {
    			th t = new th(i);
    			t.start();
    		}
    	}
    }
    
    class th extends Thread {
    	private int number = 0;
    
    	public th(int _number) {
    		number = _number;
    	}
    	@Override
    	public void run() {
    		boolean bo = true;
    		while (bo) {
    			int state = 0;
    			state = (Integer) test.chm.get("test");
    			if (state == 9) {
    				System.out.println("线程:" + number + ",停止!");
    				bo = false;
    			} else {
    				System.out.println("线程:" + number + ",state=" + state + ",time:" + System.currentTimeMillis());
    			}
    		}
    	}
    }
    
    class tht extends Thread {
    	public tht() {
    	}
    	@Override
    	public void run() {
    		boolean bo = true;
    		while (bo) {
    			int state = 0;
    			state = (int) (Math.random() * 1000000);
    			test.chm.put("test", state);
    			if (state == 9) {
    				System.out.println("线程:-1,停止,time=" + System.currentTimeMillis()
    						+ ",--------------------------------------------");
    				bo = false;
    			}
    		}
    	}
    }

    运行多次运行后出现结果:

    线程:237,state=178474,time:1348219230671
    线程:-1,停止,time=1348219230671,--------------------------------------------
    线程:236,state=178474,time:1348219230671

    线程:337,state=178474,time:1348219230671

    线程:876,state=178474,time:1348219230671

    ConcurrentHashMap不是线程安全的么,那么多个线程同时读和改的时候,从运行结果看改的线程获取到锁以后,读的线程还是可以继续执行的.到底怎么使用ConcurrentHashMap才能保证数据一致?

    问题补充:正常应该是,改state赋值为9后,所有读线程停止工作.但改的线程put时,读的线程并没有等待放锁后在读呢?

    解答:
    我不知道这位兄台有没有测试过,加不加synchronized效果是一样的;本身ConcurrentHashMap本身就是线程安全的,这个安全只存在于put和get操作,之所以出现楼主这种情况,就是你说的线程调度问题,楼主把这个//System.out.println("线程:"+number+",停止!");  去掉注释后运行,是不是可以看到所有的线程最终停止了;前面多了些
    线程:236,state=178474,time:1348219230671
    线程:337,state=178474,time:1348219230671
    线程:876,state=178474,time:1348219230671
    
    这样的信息,为什么?
    那是因为在chm被插入9之前,有些线程比如A线程运行到int state = (Integer)test.chm.get("test"); 此时得到state不是9,线程调度切换到插入9的线程B,此test.chm被插入9,B结束;切换为A继续执行,发什么什么,打印了这句:
    线程:236,state=178474,time:1348219230671
    因为这里的state是插入9之前的值;
    什么时候结束,下一次循环重新得到的state就是9了。
    所以说不论加不加synchronzied都会出现这种效果,线程调度的问题;
    
    总结:
    (1)ConcurrentMap是线程安全的,这种安全只存在于对他自己的操作,不能保证外部;
    (2)线程调度可能引起开始错误的结果。
















  2. ======================To be Continued======================
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值