基础知识整理(1)java基础一

Java基础一

一个测控够转行互联网,最近在找工作,一些基础知识,读书笔记,整理复习一下,比较菜,错误望指出。参考书籍:深入理解Java虚拟机

Java内存模型

物理机并发

一个运算过程比如计算a=a+1,其中到基本操作包含来从物理内存里读取a到值,处理器计算a+1的结果,然后把计算结果a=?保存到物理内存里面去。一个最基本的运算任务包含了处理器的计算以及内存交互即I/O操作,但是由于存储设备与处理器到计算速度相差很大,因此这个过程会直接影响处理器到处理单个任务到时间,就不能充分发挥处理器性能。因此现在到计算机一般都会加一个高速缓存来当缓冲,把运算需要到数据a到值保存到缓存里,可以让运算快速进行,当运算结束后,再放到缓存里,让缓存同步到内存,这样处理器就可以不要等那段因为运算速率差带来的时间了。下图是运算任务中到交互关系:


由于每个处理器有自己到缓存,而又共享一个主内存,这就会导致可能发生缓存里到数据不一致,因此需要一个缓存一致性协议

Java内存里的并发

首先看下Java内存里的运算任务交互关系


Java内存模型到主要目标是定义程序中各个变量到访问规则,这里到变量指的是实例变量,静态变量和数组元素。,局部变量是线程私有到,因此不会发生共享问题。下面用代码来验证下是否线程安全的

  1. 静态变量:
package Thread;

public class StaticVar {
    public static void main(String[] args) {
        Runnable staticText=new textStatic();
        Thread thread1=new Thread(staticText,"Thread1");
        Thread thread2=new Thread(staticText,"Thread2");
        thread1.start();
        thread2.start();
    }
}

class textStatic implements Runnable{
static int var=0;
    @Override
    public void run() {
        for (int i=0;i<=10;i++){
            var+=1;
            try {
                Thread.sleep(300);
            }catch (Exception e){
               e.printStackTrace();
            }
            System.out.println(Thread.currentThread().getName()+"  "+var);
        }
    }
}

输出结果:

Thread1  2
Thread2  3
Thread1  4
Thread2  5
Thread1  6
Thread2  6
Thread1  8
Thread2  9
Thread1  10
Thread2  10
Thread1  12
Thread2  12
Thread1  14
Thread2  14
Thread1  16
Thread2  17
Thread1  18
Thread2  18
Thread1  20
Thread2  20
Thread1  22
Thread2  22
  1. 实例变量:
package Thread;

public class InstanceVar {

    public static void main(String[] args) {
        Runnable InstanceText=new textInstance();
        Thread thread1=new Thread(InstanceText,"Thread1");
        Thread thread2=new Thread(InstanceText,"Thread2");
        thread1.start();
        thread2.start();
    }
}

class textInstance implements Runnable{
     int instance=0;
    @Override
    public void run() {
        for (int i=0;i<=10;i++){
            ++instance;
            try {
                Thread.sleep(300);
            }catch (Exception e){
                e.printStackTrace();
            }
            System.out.println(Thread.currentThread().getName()+"  "+instance);
        }
    }
}

输出结果:

Thread2  2
Thread1  3
Thread2  4
Thread1  4
Thread2  6
Thread1  6
Thread1  8
Thread2  8
Thread1  10
Thread2  10
Thread1  12
Thread2  13
Thread1  14
Thread2  14
Thread2  16
Thread1  16
Thread2  18
Thread1  19
Thread2  20
Thread1  20
Thread2  22
Thread1  22

Process finished with exit code 0
  1. 局部变量
package Thread;

public class LocalVar {
    public static void main(String[] args) {
        Runnable LocalText=new textLocal();
        Thread thread1=new Thread(LocalText,"Thread1");
        Thread thread2=new Thread(LocalText,"Thread2");
        thread1.start();
        thread2.start();
    }
}

class textLocal implements Runnable{
    @Override
    public void run() {
        int locals=0;
        for (int i=0;i<=10;i++){
            locals++;
            try {
                Thread.sleep(300);
            }catch (Exception e){
                e.printStackTrace();
            }
            System.out.println(Thread.currentThread().getName()+"  "+locals);
        }
    }
}

输出结果:

扫描二维码关注公众号,回复: 1882874 查看本文章
Thread2  1
Thread1  1
Thread2  2
Thread1  2
Thread2  3
Thread1  3
Thread2  4
Thread1  4
Thread2  5
Thread1  5
Thread2  6
Thread1  6
Thread2  7
Thread1  7
Thread2  8
Thread1  8
Thread2  9
Thread1  9
Thread2  10
Thread1  10
Thread2  11
Thread1  11

Process finished with exit code 0

由上面可以看出,实例变量和静态变量都算线程共有到,局部变量是线程私有到。

内存间交互操作

主要包含里8个步骤

  1. lock和unlock 锁定变量供一条线程使用与解锁供其他线程使用。作用于主内存;
  2. read和load 读取主内存变量,载入工作内存,必须顺序执行;
  3. use和assign 把工作内存里到变量传给处理器处理和把处理结果传给工作内存;
  4. store和write把工作内存变量传给主内存和保存从store得到到值,必须顺序执行。

Volatile

Volatile变量对于各个线程有可见性,即在改变值后其他线程马上知道,普通变量只能通过主内存进行共享。由于Java运算到非原子性,因此也不能保证线程安全,只有满足下面两个条件时才能保证安全:

  1. 运算结果不依赖变量当前值,或者保证只有一条线程改变变量的值。
  2. 禁止指令重排序优化。

Volatile变量的读操作和普通变量无区别,但是写操作会慢点,因为他禁止里重排序优化。

线程状态

  1. New状态 创建后未运行状态。
  2. Runable状态 正在执行或系统正在为他分配执行时间。
  3. Waiting 无限期等待,直到被执行notify()和notifyAll()方法执行,可以通过执行Object.wait()方法,Thread.join()和Lock.Support.park()方法进入此状态。
  4. TimedWaiting 限期等待,通过Thread.sleep(),Object.wait(Timeout),Thread.join(TImeout),LockSupport.parkNanos(),LockSupport.parkUntil()方法进入此状态。
  5. Blocked状态 其他线程占用排他锁
  6. Terminated 线程结束运行。

猜你喜欢

转载自blog.csdn.net/Fourier233/article/details/80908684