匿名内部类的线程安全问题

憨人啊 2018-10-11 05:44:25
public class VolatileLearn {

public static void main(String[] args) {
NumberRange num = new NumberRange();
num.setLower(0);
num.setUpper(5);

new Thread(new Runnable() {
@Override
public void run() {
// TODO Auto-generated method stub
num.setLower(4);
}
}).start();


new Thread(new Runnable() {
@Override
public void run() {
// TODO Auto-generated method stub
num.setUpper(3);
}
}).start();




}
}

package concurrent;
public class NumberRange {
private int lower, upper;

public int getLower() { return lower; }
public int getUpper() { return upper; }

public void setLower(int value) {
if (value > upper)
throw new IllegalArgumentException(value+" value > upper"+upper);
lower = value;
}

public void setUpper(int value) {
if (value < lower)
throw new IllegalArgumentException(value+" value < lower"+lower);
upper = value;
}
}

为啥我这个代码没有出现线程安全问题呀?
...全文
513 9 打赏 收藏 转发到动态 举报
写回复
用AI写文章
9 条回复
切换为时间正序
请发表友善的回复…
发表回复
憨人啊 2018-10-31
  • 打赏
  • 举报
回复
引用 2 楼 qq_40064948 的回复:

调换两个线程的位置之后,就会报你抛出的另外一个异常。
说明虽然是开了两个线程来操作数据,你想要的结果是 运行你的代码时,他先设置3然后再设置4,或者数据的线程安全问题是把。
但是你代码里不存在这个问题,cpu是切换着执行的,怎么说呢,就是 虽然是两个线程,但是 A线程先被开辟,然后再去开辟8线程,再AB都是同样的代码的情况的下,A线程肯定是比B先执行完,所以这时候4已经设置完了。你想测试线程安全问题,需要用两个线程去访问同一个方法或者数据。

怎么模拟呀?
憨人啊 2018-10-31
  • 打赏
  • 举报
回复
引用 1 楼 nayi_224 的回复:
没看懂想要干什么,你这个代码100%会报
Exception in thread "Thread-1" java.lang.IllegalArgumentException: 3 value < lower4

就是想模拟多个线程同时访问的时候,会出现【4,3】的情况,可是不晓得怎么做。
憨人啊 2018-10-31
  • 打赏
  • 举报
回复
引用 1 楼 nayi_224 的回复:
没看懂想要干什么,你这个代码100%会报
Exception in thread "Thread-1" java.lang.IllegalArgumentException: 3 value < lower4


就是想模拟多个线程访问的时候可能会出现【4,3】的情况,可是不晓得怎么模拟出来这个结果
qybao 2018-10-31
  • 打赏
  • 举报
回复
上面是 "4 > 0"
qybao 2018-10-31
  • 打赏
  • 举报
回复
一次测试可能不能达到效果,多次测试试试

public static void main(String[] args) {
        NumberRange num = new NumberRange();
        num.setLower(0);
        num.setUpper(5);
        while(true) {
        	try {
		        new Thread(new Runnable() {
		            @Override
		            public void run() {
		                // TODO Auto-generated method stub
		                num.setLower(4);
		            }
		        }).start();
		         
		         
		        new Thread(new Runnable() {
		            @Override
		            public void run() {
		                // TODO Auto-generated method stub
		                num.setUpper(3);
		            }
		        }).start();    
        	} catch (Exception e) {
        		if (e.toString().indexOf("4 > 3") > 0) {
        			System.out.println("raise exeption:4 > 3");
        			throw e
        		}
        	}
        }
}
nayi_224 2018-10-31
  • 打赏
  • 举报
回复
赋值是瞬间完成的,你需要搞一个时间差。
package test.gt50;

public class VolatileLearn {
	
	public static void main(String[] args) {
		final NumberRange num = new NumberRange();
		num.setLower(0);
		num.setUpper(5);
		
		new Thread(new Runnable() {
			@Override
			public void run() {
				// TODO Auto-generated method stub
				num.setLower(4);
			}
		}).start();
		
		
		new Thread(new Runnable() {
			@Override
			public void run() {
				// TODO Auto-generated method stub
				num.setUpper(3);
			}
		}).start();
		
	}
}

class NumberRange {
    private int lower, upper;
  
    public int getLower() { return lower; }
    public int getUpper() { return upper; }
  
    public void setLower(int value) { 
    	try {
			Thread.sleep(2000l);
		} catch (InterruptedException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
        if (value > upper) 
            throw new IllegalArgumentException(value+"  value > upper"+upper);
        
        lower = value;
        System.out.println("set lower in_value : " + value + ", now : [" + lower + "_" + upper + "]");
    }
  
    public void setUpper(int value) { 
        if (value < lower) 
            throw new IllegalArgumentException(value+"  value < lower"+lower);
        
        try {
			Thread.sleep(3000l);
		} catch (InterruptedException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
        upper = value;
        System.out.println("set upper in_value : " + value + ", now : [" + lower + "_" + upper + "]");
    }
}
Silly-77 2018-10-12
  • 打赏
  • 举报
回复

调换两个线程的位置之后,就会报你抛出的另外一个异常。
说明虽然是开了两个线程来操作数据,你想要的结果是 运行你的代码时,他先设置3然后再设置4,或者数据的线程安全问题是把。
但是你代码里不存在这个问题,cpu是切换着执行的,怎么说呢,就是 虽然是两个线程,但是 A线程先被开辟,然后再去开辟8线程,再AB都是同样的代码的情况的下,A线程肯定是比B先执行完,所以这时候4已经设置完了。你想测试线程安全问题,需要用两个线程去访问同一个方法或者数据。
nayi_224 2018-10-12
  • 打赏
  • 举报
回复
没看懂想要干什么,你这个代码100%会报 Exception in thread "Thread-1" java.lang.IllegalArgumentException: 3 value < lower4
kimsung 2018-10-12
  • 打赏
  • 举报
回复
????? 这个代码, 怎么做都不会不报错。 100%报错。 和线程没毛线关系啊。

50,504

社区成员

发帖
与我相关
我的任务
社区描述
Java相关技术讨论
javaspring bootspring cloud 技术论坛(原bbs)
社区管理员
  • Java相关社区
  • 小虚竹
  • 谙忆
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧