登录
首页 >  文章 >  java教程

java两个线程对变量进行加1操作实例分析

来源:亿速云

时间:2024-04-25 19:00:41 235浏览 收藏

目前golang学习网上已经有很多关于文章的文章了,自己在初次阅读这些文章中,也见识到了很多学习思路;那么本文《java两个线程对变量进行加1操作实例分析》,也希望能帮助到大家,如果阅读完后真的对你学习文章有帮助,欢迎动动手指,评论留言并分享~

1--错误的常规写法

<code>public static int i=0;</code><code>public static void add(){</code><code>    i=i+1;</code><code>    action();</code><code>}</code><code>public static void action(){</code><code>    System.out.println("==>"+Thread.currentThread().getName()+":"+i);</code><code>}</code><code>public static void main(String[] args) throws InterruptedException {</code><code>    Thread t1 = new Thread(SysUserServiceImpl::add,"t1");</code><code>    Thread t2= new Thread(SysUserServiceImpl::add,"t2");</code><code>    t1.start();</code><code>    t2.start();</code><code>}</code><code>运行结果==></code><code>==>t1:1</code><code>==>t2:2</code><code><br></code><code>==>t1:2</code><code>==>t2:1</code><code><br></code><code>==>t1:2</code><code>==>t2:2</code>

每次运行结果不一致,多线程环境下,t1对共享内存中的i进行+1操作,但未将值刷新到主内存,此时恰好t2也对i取到还是0进行+1操作,使得最后结果i都为1,同理t1处理完为1,t2处理完为2。多次运行结果都不一致。

改进方法1 --同步锁

<code>public class ThreadException {</code><code>    public static volatile int i=0;</code><code>    public static void add(){</code><code>        synchronized (ThreadException.class){</code><code>            i=i+1;</code><code>            action();</code><code>        }</code><code>    }</code><code>    public static void action(){</code><code>        System.out.println("==>"+Thread.currentThread().getName()+":"+i);</code><code>    }</code><code>    public static void main(String[] args) throws InterruptedException {</code><code>        Thread t1 = new Thread(ThreadException::add,"t1");</code><code>        Thread t2= new Thread(ThreadException::add,"t2");</code><code>        t1.start();</code><code>        t2.start();</code><code><br></code><code>    }</code><code>}</code>

优点:实现简单

缺点:加锁粒度大,性能低下,分布式环境,多JVM条件,synchronized失效,synchronized 只是本地锁,锁的也只是当前jvm下的对象,在分布式场景下,要用分布式锁

改进方法2 AtomicInteger

public class ThreadException {    private static AtomicInteger num = new AtomicInteger(0);    public static void add(){        int i = num.getAndIncrement();        action(i);    }    public static void action(int i){        System.out.println("由"+i+"==>"+Thread.currentThread().getName()+":"+num);    }    public static void main(String[] args) throws InterruptedException {        Thread t1 = new Thread(ThreadException::add,"t1");        Thread t2= new Thread(ThreadException::add,"t2");        t1.start();        t2.start();    }}

改进方法3  lock

<code>public class ThreadException {</code><code>    public static volatile int i=0;</code><code>    public static void action(){</code><code>        System.out.println("==>"+Thread.currentThread().getName()+":"+i);</code><code>    }</code><code><br></code><code>    static Lock lock=new ReentrantLock();</code><code>    public static void inc() {</code><code>        lock.lock();</code><code>        try {</code><code>            Thread.sleep(1);</code><code>            i=i+1;</code><code>            action();</code><code>        } catch (InterruptedException e) {</code><code>            e.printStackTrace();</code><code>        } finally {</code><code>            lock.unlock();</code><code>        }</code><code>    }</code><code>    public static void main(String[] args) throws InterruptedException {</code><code>        Thread t1 = new Thread(ThreadException::inc,"t1");</code><code>        Thread t2= new Thread(ThreadException::inc,"t2");</code><code>        t1.start();</code><code>        t2.start();</code><code>    }</code><code>}</code><code><br></code>

分布式锁:保证多个节点同步执行
实现方案:1。基于数据库,2.基于redis缓存,3.基于zookeeper

以上就是本文的全部内容了,是否有顺利帮助你解决问题?若是能给你带来学习上的帮助,请大家多多支持golang学习网!更多关于文章的相关知识,也可关注golang学习网公众号。

声明:本文转载于:亿速云 如有侵犯,请联系study_golang@163.com删除
相关阅读
更多>
最新阅读
更多>
课程推荐
更多>