java多线程并发之synchonized

 

 

1、Java实现多线程目的

Java中实现多线程利计算机多核cup并行处理多个线程,提升CUP的利用率,提升程序的处理速度。

当使用多线程进行并发编程时,当有共享资源时,就需要我们考虑线程安全问题。

如下图,假设改计算机有3个CUP,单对共享变量进行自增时。

java多线程并发之synchonized_第1张图片

cup在处理时,会将共享内存缓存到L1,L2,L3高速缓存中,当三个线程同时对i进行自增时,在缓存中拷贝的都是不可以预测,造成自增后的结果也是不可以预测,总是会小于或者等于3

public class ThreadDemo1 implements Runnable {

    private static int i=0;
    @Override
    public void run() {
        try {
            Thread.sleep(400);
        } catch (InterruptedException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
        increment();
        System.out.println("完成处理");
    }

    public /*synchronized */void increment() {
        i++;
    }
    
    public static void main(String[] args) {
        ThreadDemo1 task=new ThreadDemo1();
        for(int i=0;i<3;i++) {
            new Thread(task).start();
        }
        try {
            Thread.sleep(2000);
        } catch (InterruptedException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
        System.out.println(i);
    }
}

结果:

完成处理
完成处理
完成处理
1

如何解决这个问题,就需使用到我们的锁机制了,实现锁的方式有关键字synchronized,以及java.util.concurrent包下的lock类。

在此,我看看synchronized实现,代码如下:

package synchronizeduse;

public class ThreadDemo1 implements Runnable {

    private static int i=0;
    @Override
    public void run() {
        try {
            Thread.sleep(400);
        } catch (InterruptedException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
        increment();
        System.out.println("完成处理");
    }

    public synchronized void increment() {
        i++;
    }
    
    public static void main(String[] args) {
        ThreadDemo1 task=new ThreadDemo1();
        for(int i=0;i<3;i++) {
            new Thread(task).start();
        }
        try {
            Thread.sleep(2000);
        } catch (InterruptedException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
        System.out.println(i);
    }
}

结果:

完成处理
完成处理
完成处理
3

其原因就是synchronized关键加了一道管道锁,多个线程在访问资源是要竞争锁,没有竞争到锁的线程就需阻塞,从而实现线程串行化访问共享资源,原理如下图

 

java多线程并发之synchonized_第2张图片

 

在处理多线程性能优化时,我们一般优化的点在哪里?

1、减小锁定粒度(类锁,对象锁等),尽量减小锁住的代码块,这是我们平时业务代码所要考虑

2、 锁本身的优化。

synchronized底层就进行了一系列优化,依次实现:

无锁->偏向锁(cas操作)->轻量级锁->重量级锁

 

 

 

 

 

 

 

 

 

你可能感兴趣的:(java并发编程,JavaSe)