下面是关于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 |