多线程---线程安全(synchronized)

下面是关于synchronized的使用场景:

用两个线程完成100000次累加操作

具体遇到的情况:

1.

同一线程对象 修改 同一共享变量

用synchronized关键字修饰方法

复制代码
/**
 * 创建两个线程,利用多线程完成100000累加操作
 * 同一线程对象   修改  同一共享变量
 * 用synchronized关键字修饰方法
 */
public class Demo_01 {
    public static void main(String[] args) throws InterruptedException {
        Count count = new Count();
        Thread th1 = new Thread(() -> {
            for (int i = 0; i < 50000; i++) {
                count.increase();
            }
        });
        Thread th2 = new Thread(() -> {
            for (int i = 0; i < 50000; i++) {
                count.increase();
            }
        });
        //启动线程
        th1.start();
        th2.start();
        //等待线程执行完毕
        th1.join();
        th2.join();
        //打印结果,预期结果为:100000
        System.out.println(count.count);
    }
}
class Count {
    int count = 0;
    public synchronized void increase() {
        count++;
    }
}

2.

不同 线程对象 修改 同一共享变量

用synchronized关键字修饰代码块

复制代码
/**
 * 创建两个线程,利用多线程完成100000累加操作
 * 不同  线程对象   修改  同一共享变量
 * 用synchronized关键字修饰代码块
 */
public class Demo_02 {
    public static void main(String[] args) throws InterruptedException {
        Count02 count = new Count02();
        Thread th1 = new Thread(() -> {
            for (int i = 0; i < 50000; i++) {
                count.increase();
            }
        });
        Thread th2 = new Thread(() -> {
            for (int i = 0; i < 50000; i++) {
                count.increase();
            }
        });
        //启动线程
        th1.start();
        th2.start();
        //等待线程执行完毕
        th1.join();
        th2.join();
        //打印结果,预期结果为:100000
        System.out.println(count.count);
    }
}
class Count02 {
    int count = 0;
    public void increase() {
        synchronized (this) {
            count++;
        }
    }
}

3.

一个用synchronized关键字修饰代码块

另一个不用synchronized修饰

复制代码
/**
 * 不同  线程对象   修改  同一共享变量
 * 一个用synchronized关键字修饰代码块
 * 另一个不用synchronized修饰
 */
public class Demo_03 {
    public static void main(String[] args) throws InterruptedException {
        Count03 count = new Count03();
        Thread th1 = new Thread(() -> {
            for (int i = 0; i < 50000; i++) {
                count.increase();
            }
        });
        Thread th2 = new Thread(() -> {
            for (int i = 0; i < 50000; i++) {
                //没用synchronized修饰
                count.increase1();
            }
        });
        //启动线程
        th1.start();
        th2.start();
        //等待线程执行完毕
        th1.join();
        th2.join();
        //打印结果,预期结果为:100000
        System.out.println(count.count);
        //实际不到100000 有线程安全问题
    }
}
class Count03 {
    int count = 0;
    public void increase() {
        synchronized (this) {
            count++;
        }
    }
    public void increase1() {
        count++;
    }
}

4.

不同 线程对象 执行synchronized方法 修改全局变量

复制代码
/**
 * 不同  线程对象  执行synchronized方法 修改全局变量
 */
public class Demo_04 {
    public static void main(String[] args) throws InterruptedException {
        Count04 count1 = new Count04();
        Count04 count2 = new Count04();
        Thread th1 = new Thread(() -> {
            for (int i = 0; i < 50000; i++) {
                count1.increase();
            }
        });
        Thread th2 = new Thread(() -> {
            for (int i = 0; i < 50000; i++) {
                //没用synchronized修饰
                count2.increase();
            }
        });
        //启动线程
        th1.start();
        th2.start();
        //等待线程执行完毕
        th1.join();
        th2.join();
        //打印结果,预期结果为:100000
        System.out.println(count1.count);
        //实际不到100000 有线程安全问题
    }
}
class Count04 {
    public static int count = 0;
    public synchronized void increase() {
            count++;
    }
}

5.

多个实例对象调用synchronized方法

新new一个对象作为 锁对象 锁代码块
对全局变量进行累加

复制代码
/**
 * 多个实例对象调用synchronized方法
 * 新new一个对象作为 锁对象  锁代码块
 * 对全局变量进行累加
 */
public class Demo_05 {
    public static void main(String[] args) throws InterruptedException {
        Count05 count1 = new Count05();
        Count05 count2 = new Count05();
        Thread th1 = new Thread(() -> {
            for (int i = 0; i < 50000; i++) {
                count1.increase();
            }
        });
        Thread th2 = new Thread(() -> {
            for (int i = 0; i < 50000; i++) {
                //没用synchronized修饰
                count2.increase();
            }
        });
        //启动线程
        th1.start();
        th2.start();
        //等待线程执行完毕
        th1.join();
        th2.join();
        //打印结果,预期结果为:100000
        System.out.println(count1.count);
        //实际不到100000 有线程安全问题
    }
}
class Count05 {
    Object locker = new Object();
    static int count = 0;
    public void increase () {
        synchronized (locker) {
            count++;
        }
    }
}

6.

一个实例对象

新new一个对象作为 锁对象 锁代码块
对全局变量进行累加

复制代码
/**
 * 一个实例对象
 * 新new一个对象作为 锁对象  锁代码块
 * 对全局变量进行累加
 */
public class Demo_06 {
    public static void main(String[] args) throws InterruptedException {
        Count06 count1 = new Count06();
        Thread th1 = new Thread(() -> {
            for (int i = 0; i < 50000; i++) {
                count1.increase();
            }
        });
        Thread th2 = new Thread(() -> {
            for (int i = 0; i < 50000; i++) {
                //没用synchronized修饰
                count1.increase();
            }
        });
        //启动线程
        th1.start();
        th2.start();
        //等待线程执行完毕
        th1.join();
        th2.join();
        //打印结果,预期结果为:100000
        System.out.println(count1.count);
        //符合预期
    }
}
class Count06 {

    public static int count = 0;

    Object locker = new Object();

    public void increase() {
        synchronized (locker) {
            count++;
        }
    }
}

7.

一个实例对象 分别调用两个方法 对应同一个锁对象

新new一个对象作为 锁对象 锁代码块
对全局变量进行累加

复制代码
package Demo_201;

/**
 * 一个实例对象  分别调用两个方法 对应同一个锁对象
 * 新new一个对象作为 锁对象  锁代码块
 * 对全局变量进行累加
 */
public class Demo_07 {
    public static void main(String[] args) throws InterruptedException {
        Count07 count1 = new Count07();
        Thread th1 = new Thread(() -> {
            for (int i = 0; i < 50000; i++) {
                count1.increase();
            }
        });
        Thread th2 = new Thread(() -> {
            for (int i = 0; i < 50000; i++) {
                //没用synchronized修饰
                count1.increase1();
            }
        });
        //启动线程
        th1.start();
        th2.start();
        //等待线程执行完毕
        th1.join();
        th2.join();
        //打印结果,预期结果为:100000
        System.out.println(count1.count);
        //符合预期
    }
}
class Count07 {

    public static int count = 0;

    Object locker = new Object();

    public void increase() {
        synchronized (locker) {
            count++;
        }
    }
    public void increase1() {
        synchronized (locker) {
            count++;
        }
    }
}

8.

两个实例对象 使用静态全局对象 作为锁对象

新new一个对象作为 锁对象 锁代码块
对全局变量进行累加

复制代码
package Demo_201;

/**
 * 两个实例对象  使用静态全局对象  作为锁对象
 * 新new一个对象作为 锁对象  锁代码块
 * 对全局变量进行累加
 */
public class Demo_08 {
    public static void main(String[] args) throws InterruptedException {
        Count08 count1 = new Count08();
        Count08 count2 = new Count08();
        Thread th1 = new Thread(() -> {
            for (int i = 0; i < 50000; i++) {
                count1.increase();
            }
        });
        Thread th2 = new Thread(() -> {
            for (int i = 0; i < 50000; i++) {
                //没用synchronized修饰
                count2.increase();
            }
        });
        //启动线程
        th1.start();
        th2.start();
        //等待线程执行完毕
        th1.join();
        th2.join();
        //打印结果,预期结果为:100000
        System.out.println(count1.count);
        //符合预期
    }
}
class Count08 {

    public static int count = 0;

    static Object locker = new Object();

    public void increase() {
        synchronized (locker) {
            count++;
        }
    }
}

9.

两个实例对象 使用 类对象Count09.class 作为锁对象

新new一个对象作为 锁对象 锁代码块
对全局变量进行累加

复制代码
package Demo_201;

/**
 * 两个实例对象  使用  类对象Count09.class  作为锁对象
 * 新new一个对象作为 锁对象  锁代码块
 * 对全局变量进行累加
 */
public class Demo_09 {
    public static void main(String[] args) throws InterruptedException {
        Count09 count1 = new Count09();
        Count09 count2 = new Count09();
        Thread th1 = new Thread(() -> {
            for (int i = 0; i < 50000; i++) {
                count1.increase();
            }
        });
        Thread th2 = new Thread(() -> {
            for (int i = 0; i < 50000; i++) {
                //没用synchronized修饰
                count2.increase();
            }
        });
        //启动线程
        th1.start();
        th2.start();
        //等待线程执行完毕
        th1.join();
        th2.join();
        //打印结果,预期结果为:100000
        System.out.println(count1.count);
        //符合预期
    }
}
class Count09 {

    public static int count = 0;


    public void increase() {
        synchronized (Count09.class) {
            count++;
        }
    }
}

10.

两个实例对象 使用 类对象String.class 作为锁对象

新new一个对象作为 锁对象 锁代码块
对全局变量进行累加

复制代码
/**
 * 两个实例对象  使用  类对象String.class  作为锁对象
 * 新new一个对象作为 锁对象  锁代码块
 * 对全局变量进行累加
 */
public class Demo_10 {
    public static void main(String[] args) throws InterruptedException {
        Count10 count1 = new Count10();
        Count10 count2 = new Count10();
        Thread th1 = new Thread(() -> {
            for (int i = 0; i < 50000; i++) {
                count1.increase();
            }
        });
        Thread th2 = new Thread(() -> {
            for (int i = 0; i < 50000; i++) {
                //没用synchronized修饰
                count2.increase();
            }
        });
        //启动线程
        th1.start();
        th2.start();
        //等待线程执行完毕
        th1.join();
        th2.join();
        //打印结果,预期结果为:100000
        System.out.println(count1.count);
        //符合预期
    }
}
class Count10 {

    public static int count = 0;


    public void increase() {
        synchronized (String.class) {
            count++;
        }
    }
}

总结:

|--------------------------------------------------------------------|----------|
| 双线程累加100000操作 | 结果 |
| 同一线程对象 修改 同一共享变量 用synchronized关键字修饰方法 | 100000 |
| 不同 线程对象 修改 同一共享变量 用synchronized关键字修饰代码 | 100000 |
| 一个用synchronized关键字修饰代码块 另一个不用synchronized修饰 | 小于100000 |
| 不同 线程对象 执行synchronized方法 修改全局变量 | 小于100000 |
| 多个实例对象 调用synchronized方法 新new一个对象 作为 锁对象 锁代码块 对全局变量进行累加 | 小于100000 |
| 一个实例对象 新new一个对象作为 锁对象 锁代码块 对全局变量进行累加 | 100000 |
| 一个实例对象 分别调用两个方法 对应同一个锁对象 新new一个对象作为 锁对象 锁代码块 对全局变量进行累加 | 100000 |
| 两个实例对象 使用静态全局对象 作为锁对象 新new一个对象作为 锁对象 锁代码块 对全局变量进行累加 | 100000 |
| 两个实例对象 使用 类对象Count09.class 作为锁对象 新new一个对象作为 锁对象 锁代码块 对全局变量进行累加 | 100000 |
| 两个实例对象 使用 类对象String.class 作为锁对象 新new一个对象作为 锁对象 锁代码块 对全局变量进行累加 | 100000 |

相关推荐
亦暖筑序4 分钟前
AgentScope-Java 入门:用 Middleware 审计 Agent 调用
java·ai编程·agentscope
shylyly_12 分钟前
C++中的类型转换
开发语言·c++·匿名对象·隐式类型转换·拷贝优化
你驴我14 分钟前
WhatsApp 消息撤回与编辑的幂等性设计实践
java·服务器·前端·后端·python
cui_ruicheng1 小时前
Python数据分析(一):数据分析概述与环境搭建
开发语言·python·数据分析
青山木1 小时前
Hot 100 ---腐烂的橘子
java·数据结构·后端·算法·leetcode·广度优先
心平气和量大福大1 小时前
C#-WPF-UserControl-生命周期(加载 退出)
开发语言·c#·wpf
小龙报1 小时前
【优选算法】1. 水果成蓝 2.找到字符串中所有字母的异位词
java·c语言·数据结构·数据库·c++·redis·算法
sunywz1 小时前
【c#】 Web Deploy一键发布,IIS部署全流程
开发语言·前端·c#
自强的小白1 小时前
重点!起始时间和结束时间与创建时间和修改时间的区别(localdate与LocaldateTIME区别)以及增删改查什么时候设置目前时间(添加和更新员工时)
java
Brilliantwxx2 小时前
【Linux】 软件包管理器(yum)+ Vim使用
linux·运维·服务器·开发语言·编辑器·vim