解决方案 »
- 急!java联sqlserver报错!!!
- 在csdn中学习
- 如何才能不检查正则表达式?
- DispatchMapping[/myStruts] does not define a handler property
- 如何计算本周末的日期
- 帮忙看看这道E文题,老觉着不知道具体要干啥。有解决建议就给分:)
- Java中有没有像c#中的ref关键字来引用传值
- 反射技术的光芒好强 求解决方法
- 关于JAVASCRIPT的一个小问题,高手请进呀,帮帮小妹呀,不胜感激!
- 超郁闷问题,这个ResultSet怎么就是Read only的呢?
- Java中如何自己封装一个方法实现两个数的交换
- [求助]Mac10.9.3下安装JDK8看不到,又没法卸载,求助!
虽然你的两个线程使用的是同一个OutPut对象,但是你的output方法内并没有使用到多条线程共享的内容。
Thread A :
access the output function,
when it assign the name and len, but not access the synchronized block
Thread B: access the output function, and assign the name and len as well.
Then Thread A will print wrong information.So it should be not safe.
public static boolean isNumber(String str){
Pattern pattern = Pattern.compile("^[0-9]+$");
return pattern.matcher(str).find();
}这个呢 是线程安全的吗?
public static boolean isNumber(String str){
Pattern pattern = Pattern.compile("^[0-9]+$");
return pattern.matcher(str).find();
}这个呢 是线程安全的吗?
这当然是安全的,又没有共享资源
的确不是线程安全的,但是我们普通用的工具类,
public static boolean isNumber(String str){
Pattern pattern = Pattern.compile("^[0-9]+$");
return pattern.matcher(str).find();
}这个呢 是线程安全的吗?的确不是线程安全的,但是我们普通用的工具类,
public static boolean isNumber(String str){
Pattern pattern = Pattern.compile("^[0-9]+$");
return pattern.matcher(str).find();
}这个呢 是线程安全的吗?
public static boolean isNumber(String str){
Pattern pattern = Pattern.compile("^[0-9]+$");
return pattern.matcher(str).find();
}
public static boolean isNumber(String str){
Pattern pattern = Pattern.compile("^[0-9]+$");
return pattern.matcher(str).find();
}
但是我标题的那个例子也没有共享资源呀 怎么不是线程安全的呢
确实,你这个程序是模拟线程不安全,而不是真正的线程不安全。
给你写了一个真正线程不安全的例子,你自己运行一下,仔细分析下结果,线程这种东西需要认真细心学才能搞懂,旁人几句话也说不通。
public class ThreadTest {
private int i = 0; public static void main(String[] args) {
ThreadTest threadTest = new ThreadTest();
new Thread(threadTest.new MyThread(), "a").start();
new Thread(threadTest.new MyThread(), "b").start();
} class MyThread implements Runnable { @Override
public void run() {
while (true) {
System.out.println("线程" + Thread.currentThread().getName()
+ "运行中,现在的i值为:" + i);
try {
Thread.sleep(1000);//线程读完i后,睡眠1秒钟再对i进行修改,以便分析。
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("线程" + Thread.currentThread().getName()
+ "运行中,经过++i后,现在的i值为:" + ++i);
}
} }
}这个例子中,a、b两条线程都会去读写共享变量i值,现在会可能出现某个时候这样的情况:
线程a把i值读进来了值是0,相当于a.i==0,然后a睡眠1秒;
这时候到b线程开始读,这时候i值还是0,相当于b.i==0,b线程也开始睡眠1秒;
然后是a线程睡眠结束它又开始执行了,这回是++a.i,然后线程a会将a.i的值也就是1传回到类变量i中,这时候类变量i的值为1;
接下来b线程睡眠结束继续执行,这次是++b.i,结果b.i的值是1,然后b线程也将b.i的值传回到类变量i中,这个时候类变量i的值还是1。
这时候问题就暴露出来了,明明是执行了两次的++操作,但有效的却只有一次,这不科学了。
这个就是线程不安全的情况啦。
public class ThreadTest {
private int i = 0; public static void main(String[] args) {
ThreadTest threadTest = new ThreadTest();
new Thread(threadTest.new MyThread(), "a").start();
new Thread(threadTest.new MyThread(), "b").start();
} class MyThread implements Runnable { @Override
public void run() {
while (true) {
System.out.println("线程" + Thread.currentThread().getName()
+ "运行中,经过++i后,现在的i值为:" + ++i);
try {
Thread.sleep(500);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
} }
}
注:一个线程操作共享变量时,会先到主内存空间获取这个变量副本到线程空间中,然后在线程空间对副本进行操作,最后再把操作结果写回到主内存中去。
这个例子中,a、b两条线程都会去读写共享变量i值,现在会可能出现某个时候这样的情况:
线程a把i值读进来了值是0,相当于a.i==0;
这时候到b线程开始读,这时候i值还是0,相当于b.i==0;
然后是轮到a线程它又开始执行了,这回是++a.i,然后线程a会将a.i的值也就是1传回到类变量i中,这时候类变量i的值为1;
接下来b线程继续执行,这次是++b.i,结果b.i的值是1,然后b线程也将b.i的值传回到类变量i中,这个时候类变量i的值还是1。
这时候问题就暴露出来了,明明是执行了两次的++操作,但有效的却只有一次,这不科学了。
这个就是线程不安全的情况啦。