一. 运用 synchronized 关键字
首先我们来看看一个多线程中线程不安全的列子
代码如下:
共享数据类:
- public class NotSynchronizated extends Thread {
- private int num =10;
- @Override
- public void run(){
- try {
- System.out.println("当前线程为:"+currentThread().getName());
- num--;
- System.out.println("num 的值为:"+num);
- Thread.sleep(100);
- } catch (InterruptedException e) {
- e.printStackTrace();
- }
- }
- }
线程测试类:
- public class Text {
- public static void main(String[] args) {
- // 将共享数据放入 3 个线程里进行处理
- NotSynchronizated notSynchronizated = new NotSynchronizated();
- Thread t1=new Thread(notSynchronizated,"A");
- Thread t2=new Thread(notSynchronizated,"B");
- Thread t3=new Thread(notSynchronizated,"C");
- Thread t4=new Thread(notSynchronizated,"D");
- t1.start();
- t2.start();
- t3.start();
- t4.start();
- }
- }
在这个列子中 run 方法没有使用关键字 synchronized, 那么就会造成线程不安全, 结果如下:
那么当我们使用关键字 synchronized 后结果就会同步了, 结果如下:
那么, 在这里是对这个 run 方法进行了同步呢? 还是对这个对象进行了同步呢?
二. synchronized 同步的是对象
为了证明 synchronized 同步的是对象, 我们举出下面的代码:
共享资源类:
- public class SynchronizatedObject extends Thread {
- private int num=20;
- @Override
- public synchronized void run(){
- System.out.println("当前的线程为"+currentThread().getName());
- num--;
- System.out.println("当前 num 为"+num);
- }
- }
测试类:
- public class Text {
- public static void main(String[] args) {
- SynchronizatedObject synchronizatedObject1=new SynchronizatedObject();// 创建第一个资源共享类
- SynchronizatedObject synchronizatedObject2=new SynchronizatedObject();// 创建第二个资源共享类
- Thread t1=new Thread(synchronizatedObject1,"A");// 加入
- Thread t2=new Thread(synchronizatedObject2,"B");// 加入
- t1.start();
- t2.start();
- }
- }
结果如下:
从这里明显看出这个 synchronized 关键字同步的是对象而不是方法,
如果同步的是方法那么他将不会出现这种线程不安全的情况, 而是两对象一个一个按顺序的进入这个同步的方法里,
出现这中情况, 只能说明他是对象同步的.
所以说这段代码意思是我创建了两个对象, 同时我也创建了两把对象锁来同步话各自的 run 方法, 只不过每一条线程的调用顺序不同才会出现这样的结果.
总结: synchronized 关键字同步的是对象不是方法
来源: https://www.cnblogs.com/SAM-CJM/p/9798263.html