多线程-同步代码块中的隐患及解决办法

简介: 多线程-同步代码块中的隐患及解决办法

多线程访问同步代码块出现阻塞并解决

/**
 * 多线程访问同步代码块出现阻塞并解决
 * 锁代码块:作用的对象时整个代码块、每个对象只有一个锁与之关联
 * 阻塞原因:synchronized会将当前对象锁住,只有执行完才会释放该对象锁,下一个线程才能得到锁,从而形成互斥性
 */
public class SynchronizedCodeQuick {
    public static void main(String[] args) {
        //多线程访问会阻塞 原因没释放锁,一个对象一个锁形成互斥性
//        MyThread myThread = new MyThread();
//        Thread thread1 = new Thread(myThread, "thread1");
//        Thread thread2 = new Thread(myThread, "thread2");
//        thread1.start();
//        thread2.start();
        //多线程访问不会阻塞 两把锁互不干扰、没有互斥性
        Thread thread1 = new Thread(new MyThread(),"thread1");
        Thread thread2 = new Thread(new MyThread(),"thread2");
        thread1.start();
        thread2.start();
    }
}
class MyThread implements Runnable {
    @Override
    public void run() {
        synchronized (this) {
            for (int i = 0; i < 5; i++) {
                System.out.println("线程名:" + Thread.currentThread().getName() + ":" + i);
                try {
                    Thread.sleep(100);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        }
    }
}

注释的代码运行如下:

优化后的效果

多线程访问synchronized和非synchronized

/**
 * 多线程访问synchronized和非synchronized 并不阻塞,证实了synchronized作用范围就是被修饰的代码块
 */
public class IsBlockSynchronizedCodeQuick {
    public static void main(String[] args) {
        MyIsThread myThread = new MyIsThread();
        Thread thread1 = new Thread(myThread, "thread1");
        Thread thread2 = new Thread(myThread, "thread2");
        thread1.start();
        thread2.start();
    }
}
class MyIsThread implements Runnable {
    public void test1() {
        synchronized (this) {
            for (int i = 0; i < 5; i++) {
                System.out.println("线程名" + Thread.currentThread().getName() + ":" + i);
                try {
                    Thread.sleep(100);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        }
    }
    public void test2() {
        for (int i = 0; i < 5; i++) {
            System.out.println("线程名" + Thread.currentThread().getName() + ":" + i);
            try {
                Thread.sleep(100);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }
    @Override
    public void run() {
        String name = Thread.currentThread().getName();
        if("thread1".equals(name)){
            test1();
        }else {
            test2();
        }
    }
}

总结:

目录
相关文章
|
30天前
|
Java 开发者 C++
Java多线程同步大揭秘:synchronized与Lock的终极对决!
Java多线程同步大揭秘:synchronized与Lock的终极对决!
58 5
|
30天前
|
安全 Java 开发者
Java多线程同步:synchronized与Lock的“爱恨情仇”!
Java多线程同步:synchronized与Lock的“爱恨情仇”!
80 5
|
30天前
|
Java 程序员
从0到1,手把手教你玩转Java多线程同步!
从0到1,手把手教你玩转Java多线程同步!
21 3
|
30天前
|
Java 测试技术
Java多线程同步实战:从synchronized到Lock的进化之路!
Java多线程同步实战:从synchronized到Lock的进化之路!
85 1
|
1月前
|
存储 Java 开发者
HashMap线程安全问题大揭秘:ConcurrentHashMap、自定义同步,一文让你彻底解锁!
【8月更文挑战第24天】HashMap是Java集合框架中不可或缺的一部分,以其高效的键值对存储和快速访问能力广受开发者欢迎。本文深入探讨了HashMap在JDK 1.8后的底层结构——数组+链表+红黑树混合模式,这种设计既利用了数组的快速定位优势,又通过链表和红黑树有效解决了哈希冲突问题。数组作为基石,每个元素包含一个Node节点,通过next指针形成链表;当链表长度过长时,采用红黑树进行优化,显著提升性能。此外,还介绍了HashMap的扩容机制,确保即使在数据量增大时也能保持高效运作。通过示例代码展示如何使用HashMap进行基本操作,帮助理解其实现原理及应用场景。
31 1
|
1月前
|
Java 调度 开发者
Java并发编程:解锁多线程同步的奥秘
在Java的世界里,并发编程是提升应用性能的关键所在。本文将深入浅出地探讨Java中的并发工具和同步机制,带领读者从基础到进阶,逐步掌握多线程编程的核心技巧。通过实例演示,我们将一起探索如何在多线程环境下保持数据的一致性,以及如何有效利用线程池来管理资源。无论你是初学者还是有一定经验的开发者,这篇文章都将为你打开新的视野,让你对Java并发编程有更深入的理解和应用。
|
2月前
|
安全 Java 程序员
Java 并发编程:解锁多线程同步的奥秘
【7月更文挑战第30天】在Java的世界里,并发编程是一块充满挑战的领域。它如同一位严苛的导师,要求我们深入理解其运作机制,才能驾驭多线程的力量。本文将带你探索Java并发编程的核心概念,包括线程同步与通信、锁机制、以及并发集合的使用。我们将通过实例代码,揭示如何在多线程环境中保持数据的一致性和完整性,确保你的应用程序既高效又稳定。准备好了吗?让我们一同踏上这段解锁Java并发之谜的旅程。
35 5
|
1月前
|
Java 开发者
解锁Java并发编程的秘密武器!揭秘AQS,让你的代码从此告别‘锁’事烦恼,多线程同步不再是梦!
【8月更文挑战第25天】AbstractQueuedSynchronizer(AQS)是Java并发包中的核心组件,作为多种同步工具类(如ReentrantLock和CountDownLatch等)的基础。AQS通过维护一个表示同步状态的`state`变量和一个FIFO线程等待队列,提供了一种高效灵活的同步机制。它支持独占式和共享式两种资源访问模式。内部使用CLH锁队列管理等待线程,当线程尝试获取已持有的锁时,会被放入队列并阻塞,直至锁被释放。AQS的巧妙设计极大地丰富了Java并发编程的能力。
33 0
|
1月前
|
Java
【多线程面试题十五】、synchronized可以修饰静态方法和静态代码块吗?
这篇文章讨论了Java中的`synchronized`关键字是否可以修饰静态方法和静态代码块,指出`synchronized`可以修饰静态方法,创建一个类全局锁,但不能修饰静态代码块。
|
1月前
|
Java UED
基于SpringBoot自定义线程池实现多线程执行方法,以及多线程之间的协调和同步
这篇文章介绍了在SpringBoot项目中如何自定义线程池来实现多线程执行方法,并探讨了多线程之间的协调和同步问题,提供了相关的示例代码。
251 0