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

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

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

/**
 * 多线程访问同步代码块出现阻塞并解决
 * 锁代码块:作用的对象时整个代码块、每个对象只有一个锁与之关联
 * 阻塞原因: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();
        }
    }
}

总结:

目录
相关文章
|
25天前
|
Java 开发者 C++
Java多线程同步大揭秘:synchronized与Lock的终极对决!
【6月更文挑战第20天】在Java多线程编程中,`synchronized`和`Lock`是两种关键的同步机制。`synchronized`作为内置关键字提供基础同步,简单但可能不够灵活;而`Lock`接口自Java 5引入,提供更复杂的控制和优化性能的选项。在低竞争场景下,`synchronized`性能可能更好,但在高并发或需要精细控制时,`Lock`(如`ReentrantLock`)更具优势。选择哪种取决于具体需求和场景,理解两者机制至关重要。
|
25天前
|
Java 测试技术
Java多线程同步实战:从synchronized到Lock的进化之路!
【6月更文挑战第20天】Java多线程同步始于`synchronized`关键字,保证单线程访问共享资源,但为应对复杂场景,`Lock`接口(如`ReentrantLock`)提供了更细粒度控制,包括可重入、公平性及中断等待。通过实战比较两者在高并发下的性能,了解其应用场景。不断学习如`Semaphore`等工具并实践,能提升多线程编程能力。从同步起点到专家之路,每次实战都是进步的阶梯。
|
25天前
|
Java 程序员
从0到1,手把手教你玩转Java多线程同步!
【6月更文挑战第20天】从0到1学Java多线程同步:理解线程同步关键,掌握`synchronized`用法,探索`Lock`接口,实战演练并进阶学习锁升级、`Condition`及死锁预防,成为多线程大师!
|
3天前
|
安全 算法 Linux
【Linux】线程安全——补充|互斥、锁|同步、条件变量(下)
【Linux】线程安全——补充|互斥、锁|同步、条件变量(下)
12 0
|
3天前
|
存储 安全 Linux
【Linux】线程安全——补充|互斥、锁|同步、条件变量(上)
【Linux】线程安全——补充|互斥、锁|同步、条件变量(上)
10 0
|
5天前
|
存储 安全 Java
Java面试题:请解释Java内存模型,并说明如何在多线程环境下使用synchronized关键字实现同步,阐述ConcurrentHashMap与HashMap的区别,以及它如何在并发环境中提高性能
Java面试题:请解释Java内存模型,并说明如何在多线程环境下使用synchronized关键字实现同步,阐述ConcurrentHashMap与HashMap的区别,以及它如何在并发环境中提高性能
9 0
|
10天前
|
安全 NoSQL Java
网络安全-----Redis12的Java客户端----客户端对比12,Jedis介绍,使用简单安全性不足,lettuce(官方默认)是基于Netty,支持同步,异步和响应式,并且线程是安全的,支持R
网络安全-----Redis12的Java客户端----客户端对比12,Jedis介绍,使用简单安全性不足,lettuce(官方默认)是基于Netty,支持同步,异步和响应式,并且线程是安全的,支持R
|
14天前
|
安全 Java
解决Java中多线程同步问题的方案
解决Java中多线程同步问题的方案
|
20天前
|
Java
java线程之信号同步
java线程之信号同步
20 0
|
24天前
|
安全 Java 开发者
Java多线程同步:synchronized与Lock的“爱恨情仇”!
【6月更文挑战第20天】Java多线程中,`synchronized`和`Lock`是线程安全的保障。`synchronized`简单易用,但有局限,如不可中断、无公平策略。`Lock`接口及`ReentrantLock`提供更细粒度控制,支持可中断、公平锁和条件变量,适合复杂场景。在选择时,应根据项目需求权衡简易性和灵活性。示例展示了两者用法差异,强调正确管理锁以避免死锁。理解特点,灵活应用,是多线程编程的关键。