线程安全问题出现的原因和解决方法
2017-08-11 15:27
387 查看
线程安全问题:
线程安全出现的根本原因:
1.存在两个或者两个以上的线程对象共享同一个资源;
2.多线程操作共享资源代码有多个语句。
线程安全问题的解决方案(2个):
方式一:同步代码块
格式:synchronize(锁对象){
需要被同步的代码
}
同步代码块需要注意的事项:
1.锁对象可以是任意的一个对象;
2.一个线程在同步代码块中sleep了,并不会释放锁对象;
3.如果不存在线程安全问题,千万不要使用同步代码块;
4.锁对象必须是多线程共享的一个资源,否则锁不住。
例子:三个窗口售票
class SaleTicket extends Thread{
static int num = 50;//票数 非静态的成员变量,非静态的成员变量数据是在每个对象中都会维护一份数据的。
public SaleTicket(String name) {
super(name);
}
@Override
public void run() {
while(true){
//同步代码块
synchronized ("锁") {
if(num>0){
System.out.println(Thread.currentThread().getName()+"售出了第"+num+"号票");
try {
Thread.sleep(100);
} catch (InterruptedException e) {
e.printStackTrace();
}
num--;
}else{
System.out.println("售罄了..");
break;
}
}
}
}
}
public class Demo4 {
public static void main(String[] args) {
//创建三个线程对象,模拟三个窗口
SaleTicket thread1 = new SaleTicket("窗口1");
SaleTicket thread2 = new SaleTicket("窗口2");
SaleTicket thread3 = new SaleTicket("窗口3");
//开启线程售票
thread1.start();
thread2.start();
thread3.start();
}
}
方式二:同步函数(同步函数就是使用synchronized修饰一个函数)
同步函数注意事项:
1.如果函数是一个非静态的同步函数,那么锁对象是this对象;
2.如果函数是静态的同步函数,那么锁对象是当前函数所属的类的字节码文件(class对象);
3.同步函数的锁对象是固定的,不能由自己指定。
例子:两夫妻取钱
推荐使用:同步代码块
原因:
1.同步代码块的锁对象可以由我们自由指定,方便控制;
2.同步代码块可以方便的控制需要被同步代码的范围,同步函数必须同步函数的所有代码。
线程安全出现的根本原因:
1.存在两个或者两个以上的线程对象共享同一个资源;
2.多线程操作共享资源代码有多个语句。
线程安全问题的解决方案(2个):
方式一:同步代码块
格式:synchronize(锁对象){
需要被同步的代码
}
同步代码块需要注意的事项:
1.锁对象可以是任意的一个对象;
2.一个线程在同步代码块中sleep了,并不会释放锁对象;
3.如果不存在线程安全问题,千万不要使用同步代码块;
4.锁对象必须是多线程共享的一个资源,否则锁不住。
例子:三个窗口售票
class SaleTicket extends Thread{
static int num = 50;//票数 非静态的成员变量,非静态的成员变量数据是在每个对象中都会维护一份数据的。
public SaleTicket(String name) {
super(name);
}
@Override
public void run() {
while(true){
//同步代码块
synchronized ("锁") {
if(num>0){
System.out.println(Thread.currentThread().getName()+"售出了第"+num+"号票");
try {
Thread.sleep(100);
} catch (InterruptedException e) {
e.printStackTrace();
}
num--;
}else{
System.out.println("售罄了..");
break;
}
}
}
}
}
public class Demo4 {
public static void main(String[] args) {
//创建三个线程对象,模拟三个窗口
SaleTicket thread1 = new SaleTicket("窗口1");
SaleTicket thread2 = new SaleTicket("窗口2");
SaleTicket thread3 = new SaleTicket("窗口3");
//开启线程售票
thread1.start();
thread2.start();
thread3.start();
}
}
方式二:同步函数(同步函数就是使用synchronized修饰一个函数)
同步函数注意事项:
1.如果函数是一个非静态的同步函数,那么锁对象是this对象;
2.如果函数是静态的同步函数,那么锁对象是当前函数所属的类的字节码文件(class对象);
3.同步函数的锁对象是固定的,不能由自己指定。
例子:两夫妻取钱
class BankThread extends Thread{ static int count = 5000; public BankThread(String name){ super(name); } @Override // public synchronized void run() { while(true){ synchronized ("锁") { if(count>0){ System.out.println(Thread.currentThread().getName()+"取走了1000块,还剩余"+(count-1000)+"元"); count= count - 1000; }else{ System.out.println("取光了..."); break; } } } } public class Demo1 { public static void main(String[] args) { //创建两个线程对象 BankThread thread1 = new BankThread("老公"); BankThread thread2 = new BankThread("老婆"); //调用start方法开启线程取钱 thread1.start(); thread2.start(); } }
推荐使用:同步代码块
原因:
1.同步代码块的锁对象可以由我们自由指定,方便控制;
2.同步代码块可以方便的控制需要被同步代码的范围,同步函数必须同步函数的所有代码。
相关文章推荐
- YAWL引擎运行失败出现关于log4j问题的原因和解决方法
- myEclipse 项目有红感叹号问题出现原因及解决方法
- smarty作为view时使用Zend_Form出现方法未定义的问题原因及解决
- BI publisher 安装完出现 “由于宏安全设置,无法找到宏或宏被禁用”的问题解决方法
- Java SimpleDateFormat 线程不安全问题及解决方法
- nachos编译问题出现的原因及解决方法
- Nhibernate出现No row with the given identifier exists问题的产生原因及解决方法
- 读取文本出现 锘 * 系列乱码错误(UTF-8 BOM问题)的原因及解决方法
- 解决SimpleDateFormat的线程不安全问题的方法:ThreadLocal
- Java之——SimpleDateFormat 线程不安全问题及解决方法
- 在Hiberate事务中,出现抛异常或者其它原因导致没有执行commit或rollback方法时的安全问题
- Java中long类型直接赋值出现The literal xxxxxxxxxx of type int is out of range 问题的原因和解决方法
- java解决线程不安全问题的方法
- 出现“unrecognized selector sent to instance”问题原因之一及解决方法。
- 出现“unrecognized selector sent to instance”问题原因之一及解决方法。
- 出现“unrecognized selector sent to instance”问题原因之一及解决方法。
- php 出现Warning: A non-numeric value encountered问题的原因及解决方法
- 程序中和有js函数的网页交互,线程中调用 get_Script 就会错误的解决方法,由于COM的线程安全问题
- Android类app的安全问题造成漏洞的原因以及解决方法
- QT出现“collect2 ld returned 1 exit status”问题原因及解决方法