先了解下JAVA程序在运行时内存的分布,由以下部分组成

  1. 所有线程共享一个堆;存放的都是new 出来的对象;
  2. 方法区所有线程共享一个方法区;里面存放的内容有点杂,可以认为是除堆和栈中的其它东西(如类信息,静态变量,常量,代码等);
  3. 程序计数器:也叫PC,存放下一条指令所在单元的地址的地方;
  4. JAVA栈每个线程都有一个自己的JAVA栈;存放的一般是方法的局部变量,方法出口信息等;
  5. 本地方法栈:与JAVA栈类似,区别是使用的对象不一样,本地方法栈是给Native方法使用的,JAVA栈是给JAVA方法使用的;

注意上面标红的堆和方法区的数据,是多个线程的共享的资源,会出现多个线程访问共享资源的情况;如多个线程访问同一个对象的成员变量,多个线程访问静态全局变量等...

多个线程不正确的访问共享资源

举个例子,多个线程访问同一个对象的情况,这里被访问的对象为共享资源,代码如下:

定义一个抽象类IntGenerator,类中定义一个next方法用于返回整型值,再定义一个canceled成员属性用于判断该对象是否被取消,注意canceled是boolean类型,关于canceled的操作(赋值和返回操作)都是原子性的,且canceled变量被设置为volatile,保证线程间的可见性;

package concurrency;

public abstract class IntGenerator {
    private volatile boolean canceled = false;

    public abstract int next();

    public void cancel() {
        canceled = true;
    }

    public boolean isCanceled() {
        return canceled;
    }
}
View Code

相关文章: