首页 > 编程语言 > 详细

多线程

时间:2019-10-17 13:25:21      阅读:54      评论:0      收藏:0      [点我收藏+]

1.同步方法和非同步方法是否可以同时调用

可以同时调用,可以理解为不加synchronized的方法无视这个对象的锁

    int count=10;
    public synchronized void m1(){
        count--;
        System.out.println(Thread.currentThread().getName()+"m1 started 01 : "+count);
        try {
            Thread.sleep(10000L);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        System.out.println(Thread.currentThread().getName()+"m1 started 02 : "+count);
    }
    public /*synchronized*/ void m2(){
        try {
            count--;
            Thread.sleep(5000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        System.out.println(Thread.currentThread().getName()+"m2 start ..."+count);
    }
    public static void main(String[] args) {
        Test t = new Test();
        new Thread(()->t.m1(),"m1").start();
        new Thread(()->t.m2(),"m2").start();
    }

2.对业务写方法上枷锁,业务读方法上不加锁,可能会产生脏读现象(读到在写的过程中还没有完成的数据)

     String name;
     Double price;
    public synchronized void set(String name,Double price){
        this.name=name;
        try {
            Thread.sleep(2000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        this.price=price;
    }
    public Double get(){
        return this.price;
    }
    public static void main(String[] args) {
        Test t = new Test();
        new Thread(()->t.set("zhangsan",100.00),"m1").start();

        try {
            TimeUnit.SECONDS.sleep(1);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }

        System.out.println(t.get());
        try {
            TimeUnit.SECONDS.sleep(2);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        System.out.println(t.get());
    }

3.一个同步方法可以调用另外一个同步方法,

一个线程已经拥有了某个对象的锁,再次申请的时候仍然会得到该对象的锁,也就是说synchronized获得的锁是可以重入的,子类也可以调用父类的同步方法

4.程序在执行过程中,如果出现异常

程序执行过程中如果出现异常,默认情况锁会被释放

所以在并发处理的过程中,有异常要多加小心,不然可能会发生不一致的情况,若是不想释放这个锁则加上try()catch()

5.volatile

这个和JMM有关(Java Memory Model)Java内存模型

在JMM中有一个内存为主内存(我们所说的栈内存、堆内存都可以理解为主内存),每一个线程在执行的过程中都有一个自己的内存,存放自己变量的内存。它会从主内存中读取数据,把数据放进自己的缓冲区内,然后进行操作,然而在没操作完之前,它不会再回到主内存中取读取数据,因为本地已经缓存了数据,操作完之后再写回主内存中。若是读的这条数据加上volatile,这条数据发生变化之后,就会通知其他线程,之前的数据过期了,请重新来主内存中读取数据。

注:volatile不能替代synchronized,volatile只能保证可见性,synchronized技能保证可见性,还能保证原子性,synchronized性能比volatile低

 volatile boolean running=true;
    void m(){
        System.out.println("m start");
        while (running){
        }
        System.out.println("m end");
    }

    public static void main(String[] args) {
        Test3 t = new Test3();
        new Thread(()->t.m(),"m1").start();
        try {
            TimeUnit.SECONDS.sleep(1);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }

        t.running=false;
    }

6.AtomicInteger

AtomicXXX类本身方法都是原子性的,但不能保证多个方法连续调用是原子性的。

7.细粒度的锁效率要比粗粒度的锁效率高

8.synchronized所对象

所是锁的是对象,则对的是堆内存中的对象,若是新new了一个对象,则这个对象已经不是原来的对象了,所以不能新new 这个对象。

9.不要以字符串常量作为锁的对象 

 

多线程

原文:https://www.cnblogs.com/gxlaqj/p/11691190.html

(0)
(0)
   
举报
评论 一句话评论(0
关于我们 - 联系我们 - 留言反馈 - 联系我们:wmxa8@hotmail.com
© 2014 bubuko.com 版权所有
打开技术之扣,分享程序人生!