1.线程的安全性问题是什么?使用什么场景的线程才会出现安全性问题?我们用程序来举例
这是Runable线程类
public class Runable implements Runnable{
int i = 100;
@Override
public void run() {
// TODO Auto-generated method stub
while(true) {
if(i>0) {
try {
Thread.sleep(10);//为了让安全问题明显,我们让线程执行的时间变长,故睡眠10毫秒
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
System.out.println(i);
i--;
}
}
}
}
这是Test测试类
public class Test {
public static void main(String[] args) {
// TODO Auto-generated method stub
Runable runable = new Runable();
Thread t1 = new Thread(runable);
Thread t2 = new Thread(runable);
Thread t3 = new Thread(runable);
t1.start();
t2.start();
t3.start();
}
}
运行截图
2.三个线程通知执行100个数的显示,却发现很多重复的,而有的缺跳过了显示,这就是线程的安全问题,线程的安全问题只发生在共享数据上,这也是并行线程的一个缺点,我们怎么才能防止这种事情的发送,是多线程能运行,而又不能有遗漏和重复呢
我们可以使用同步代码块,同步方法、Lock等
3.我们用同步代码块举个例子
修改Runable线程类
public class Runable implements Runnable{
int i = 100;
Object object = new Object();
@Override
public void run() {
// TODO Auto-generated method stub
while(true) {
synchronized (object) {//可存放任意对象的变量,但这个变量必须是该类的成员变量
if(i>0) {
try {
Thread.sleep(10);//为了让安全问题明显,我们让线程执行的时间变长,故睡眠10毫秒
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
System.out.println(Thread.currentThread().getName()+" "+i);
i--;
}
}
}
}
}
Test测试类代码不变
public class Test {
public static void main(String[] args) {
// TODO Auto-generated method stub
Runable runable = new Runable();
Thread t1 = new Thread(runable);
Thread t2 = new Thread(runable);
Thread t3 = new Thread(runable);
t1.start();
t2.start();
t3.start();
}
}
输出结果
4.结论:我们可以看出三条线程可以同步执行了,不再出现第一个的安全问题