线程:共享资源(一)

共享资源(或称临界资源)问题:多个线程同时修改同一个数据(资源),导致最终结果不正确,这是典型的由于并发访问所产生的问题。
线程的内存结构:
[b][size=large]当我们每启动一个线程,每个线程都会有一个它自己的栈,所以对于局部变量,不存在并发访问问题,但“堆”和“方法区”是所有线程共享的,所以,如果我们在多个线程中访问在“堆”中的同一个对象的数据时,或者访问静态变量时,就会产生并发访问问题[/size][/b]
某个线程类:
public class MyThread extends Thread {
public MyThread(String name){
super(name);
}
@Override
public void run() {
SomeClass sc = new SomeClass();
sc.dosomething();
}
}
客户端:
public class MyThreadClient {
public static void main(String[] args) {
MyThread mt = new MyThread("我的线程");
mt.start();
SomeClass sc = new SomeClass();
sc.dosomething();
}
}
SomeClass资源类:
public class SomeClass {
private int id;
private String name;
public void dosomething(){
int i = 0;
for(;i<23;i++){
System.out.println(Thread.currentThread().getName()+":"+i);
}
}
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
不存在共享资源的问题:
因为每个线程用的是他自己的对象,都有他自己的空间,不存在线程安全的问题。
即使两个线程同时进入到SomeClass中的dosomething()方法中,因为i是局部变量,又是两个不同的对象,因此是没有线程安全问题的。

在下面虽然都是用的是同一个SomeClass的对象,已经访问到同一个共享资源,但是他不存在线程安全的问题。
当我们访问这个方法的时候并没有用到共享资源,因为访问同一个对象时,这个对象时共享资源,那么这个对象的属性是共享的。但是对于局部变量,这些线程他不是共享的。比如一个线程进入dosomething这个方法时,可以知道这个方法会创建一个栈帧,然后在这个栈里边压入i这个局部变量并保存在栈中,当有另外一个线程进来时会再创建一个栈帧并压入i这个局部变量,因此从内存分析来看,这是两个不同栈帧中的不同变量,因此i这个局部变他不是共享的资源,代码如下所示:
Someclass中的部分代码:
for(;i<500;id++){ System.out.println(Thread.currentThread().getName()+":"+i);
}
具体的线程类:
public class MyThread extends Thread {
private SomeClass sc;
public MyThread(String name, SomeClass sc) {
super(name);
}
@Override
public void run() {
sc.dosomething();
}
}
客户端:
public static void main(String[] args) {
SomeClass sc = new SomeClass();
MyThread mt = new MyThread("我的线程",sc);
mt.start();
sc.dosomething();
}
现在把i局部变量改成SomeClass中的属性id的话,这个实例变量两个线程都共享他,这是就会出现共享资
源的问题,因为id是两个线程共享的变量。假设两个线程同时进来的话,稍微后进来的那个线程的id值就不
一定是从0开始了,以后输出的值也就会混乱了,就没有那么顺序的++1的递增输出
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值