黑马程序员技术交流社区
标题:
怎样解除线程安全问题
[打印本页]
作者:
HelloWorld_2013
时间:
2013-4-13 13:23
标题:
怎样解除线程安全问题
本帖最后由 HelloWorld_2013 于 2013-4-14 15:55 编辑
线程安全问题。。
作者:
易杰
时间:
2013-4-13 13:25
java多线程安全问题的解除步骤
1.明确多线程执行代码。(run方法中的代码都是多线程执行代码,如果在run方法体中调用了其他方法,那么其他方法所包含的代码也是多线程执行代码)
2.明确多线程共享数据。(创建多线程对象时传递给Thread(Object o)构造函数的对象,是共享数据(注:对象中的属性、以及包含的其他对象都是共享数据),当对象中包含其他的对象时,那么其他的对象中的所有数据也都是共享数据。
3.明确多线程执行代码中操作了共享数据的代码,将操作了共享数据的代码放入synchronized(Object o )方法体中,这样线程安全问题就解决。(注:还可使用另一种行式的代码来处理操作了共享数据的代码。它们产生的作用是一样的,只是代码的形式不同)
另一种行式:假如add(int n)方法封装了操作共享数据的代码,只需将synchronized作为修饰符,修饰add(int n)方法即可。synchronized修饰符位于访问权限修饰符之后,返回值类型之前。注:常用技巧,定义一个synchronized修饰的函数,将某处操作了共享数据的代码移到函数中,再在代码的原始位置调用该函数。
如: public synchronized void add(int n){
//将共享数据的值加上n
sum+=n;
//将共享数据的值输出
System.out.println("sum="+sum);
}
示例代码:
class Bank{
//共享数据对象中包含了Bank对象,所Bank对象中的sum也是共享数据
private int sum;
Object obj = new Object();
public void add(int n){
//将操作了共享数据sum的代码放入synchronized(Object o )方法体中
synchronized(obj ){
//将共享数据的值加上n
sum+=n;
//将共享数据的值输出
System.out.println("sum="+sum);
}
}
}
//定义共享数据对象的类。
class Cus implements Runnable{
//在共享数据对象的类创建一个Bank,所以Bank也是一个共享数据,Bank对象中所包含的数据也都是共享数据。
private Bank b = new Bank();
public void run(){
//run方法体中的代码都是多线程执行的代码。
for(int x=0; x<3; x++){
//run方法体中调用了add(int n)方法,add(int n)方法中的代码也是多线程执行的代码。
b.add(100);
}
}
}
class BankDemo{
public static void main(){
//创建Cus对象,该对象为共享数据
Cus c = new Cus();
// 创建两个线程对象,并共享数据传给两个线程对象。
Thread t1= new Thread(c);
Thread t2= new Thread(c);
//开启两个线程
t1.start();
t1.start();
}
}
作者:
山西_李帅
时间:
2013-4-13 13:26
同步线程(解决线程安全)
线程安全问题产生的原因:
多个线程通过多条语句去操作共享数据
怎样解决线程的安全问题
当某一个线程在操作数据时,它没有操作完,其它的线程是不允许操作的。
只有当这个线程执行完成后,我们才允许其它线程操作。我们管这种机制叫锁的机制.
线程同步的问题
两种解决方式
1.使用synchronized 块
synchronized(对象){
多条语句操作的数据
}
锁的对象可以是任意对象
2.使用synchronized 方法
使用同步代码块解决安全问题注意事项
所有的线程在操作时,要保证线程是安全的,
必须保证所使用的锁是同一个.
同步方法
其时就是使用synchronized去修饰一个方法.
同步代码块与同步方法的原理是一样的,
区别在于它们所控制的范围不一样。
同步方法它是将整个方法都锁定。
线程没有执行完这个方法,其它线程是不能执行的。
而同步代码块我们可以控制只方法中的某一部分去锁。
在实际操作中建议使用同步代码块。
同步的弊端:
多线程的优点:提高效率
使用同步后就使的多线程程序的效率降低.
将同步方法详细分析
同步方法它其时也是使用同步代码块实现的。
那么同步方法它所使用的锁是什么?
非静态的同步方法所使用的锁对象就是this
静态的同步方法所使用的锁对象不是this,
当前静态同步方法所使用的锁对象就是线程类的.class文件对象.
java中的所有的类都有一个静态的属性叫做.class
它的作用是得到当前类的字节码对象.
作者:
崔宝东
时间:
2013-4-14 08:49
有2种解决方法。第一,是采用原子变量,毕竟线程安全问题最根本上是由于全局变量和静态变量引起的,只要保证了对于变量的写操作要么全写要么不写,就可以解决线程安全,定义变量用sig_atomic_t和volatile。第二,就是实现线程间同步啦,用互斥索,信号量。让线程有序的访问变量就可以啦
作者:
lipingan0520
时间:
2013-4-14 10:29
1,同步代码块。
2,同步函数。掌握这2知识点,可以解决线程安全问题
作者:
庄生晓梦
时间:
2013-4-14 10:56
解决多线程的安全问题的办法是:对多条操作共享数据的语句,只能让一个线程都执行完,在执行过程中其他线程不可以参与执行。
java对多线程安全问题通过同步的方式进行解决:
同步代码块:synchronized(对象)
{
线程操作的共享数据;
}
同步函数:通过将线程操作的共享数据封装到一个方法中,用synchronized来修饰该方法。
同步函数效率要比同步代码块低,所以建议使用同步代码块。
作者:
黄玉昆
时间:
2013-4-14 14:08
如果问题未解决,请继续追问,如果没有问题了,请将帖子分类 改为“已解决”,谢谢
欢迎光临 黑马程序员技术交流社区 (http://bbs.itheima.com/)
黑马程序员IT技术论坛 X3.2