java多线程:线程安全与synchronized关键字(应用级别)

写在前面的话:本文是我个人不断学习总结试验快一个星期的结果,如果你认真去研究理解相信你也会有不小的收获!但是内容也比较长需要很大耐心去阅读,不建议一次性读完!

 

1.线程安全问题出现的根本原因是什么?

      线程安全问题出现的根本原因是由于,多个线程同时操作一个共享数据,使结果出现二义性【期望结果与获得结果相悖】。

 

2.如何更好理解线程安全?   

      举个例子:比如你有两张银行卡,一张主卡张副卡,主卡是用来自己用副卡是留给你的老婆(也可以是情人、小三,随意啦看你有多大能耐【滑稽】),将设你现在卡里只有1000元(我从小到大没见过这么多钱),有一天你和你的老婆(小三?)去不同的ATM机上同时取钱。你都打算你取了1000元以后,回家然后你的老婆骂你:死鬼,也不给我留点,糟老头子,等着挨板子吧!但是你回家以后却发现你老婆笑嘻嘻,还炫耀她把你的1000元 全取了。

线程不安全的一段代码实例:

package com.springboot.thread;

public class SynchronizedExp {
    private static  int i=0;
    public static void addI(){
        while (i<=50){
            System.out.println("Current thread is:"+Thread.currentThread().getName()+" and i is :"+i);
            i++;
        }
    }
    public static void main(String[] args) {
        Thread thread1 = new Thread("thread1"){
            @Override
            public void run() {
              addI();
            }
        };
        Thread thread2 = new Thread("thread2"){
            @Override
            public void run() {
                addI();
            }
        };
        thread1.start();
        thread2.start();
    }
}

运行结果部分:

从结果我们可以看出,thread1都已经增长到50了,而thread拿到数据还是25,如果我们数据设得更大一些那么thread2将会继续从25开始增长。假设一个场景:假设是两个车票窗口同时卖票,那么上述情景将会演变成:有一个窗口已经将25号车票卖出,由于结果没有同步造成另一个窗口继续出售25号票,这在现实生活中是绝对不允许的!(这种垃圾例子已经被别人举过无数次,但是确实比较形象有助于理解,真香!)

 

3.面试中如何回答

       线程安全问题都是由全局变量及静态变量引起的。
若每个线程中对全局变量、静态变量只有读操作,而无写操作,一般来说,这个全局变量是线程安全的;若有多个线程同时执行写操作,一般都需要考虑线程同步,否则的话就可能影响线程安全。(来源:https://blog.csdn.net/qq_35389417/article/details/80594524

 

4.如何解决多线程的安全问题?

有三种方式:分别是 同步代码块 、同步方法和锁机制(Lock)

 

5.引出synchronized关键字

    synchronized:同步

   上述解决线程安全问题中的同步代码块、同步方法均用到了synchronized。使用synchronized修饰以后就能保证在同一个时刻只能有一个线程在访问方法块或代码块。

6.如何判断synchronized是给当前的实例加锁还是给类加锁?

       正如前文所提到的那样,synchronized可以用在方法或者代码块上。方法可以分为静态方法(static修饰的方法)和普通方法(实例方法),代码块也可以分为静态代码块与非静态代码块。当synchronized用来修饰普通方法与非静态代码块时是给对象加锁,当用来修饰静态方法时给类加锁。

那么为什么是这样呢?

      如果你有java开发经验或者你系统学习过java基础知识应该知道,当我们用static修饰一个类、方法、代码块等时,他是从属于类的,在编译阶段已经被加载到java虚拟机,不需要创建对象就能被调用,所以我们可以得到上述结论。

7.给出实例:

(1).synchronized修饰普通方法

package com.springboot.thread;

public class ThreadSynchronized extends Thread{
    private int i=0;

    @Override
    public void run() {
       addI();
    }

    public synchronized void addI(){
        while (i<=50){
            System.out.println("Current thread is:"+Thread.currentThread().getName()+" and i is :"+i);
            i++;
        }
    }
}

class TestThread{
    public static void main(String[] args) {
        ThreadSynchronized threadSynchronized = new ThreadSynchronized();
        threadSynchronized.start();
    }
}

运行结果:

Current thread is:Thread-0 and i is :0
Current thread is:Thread-0 and i is :1
Current thread is:Thread-0 and i is :2
Current thread is:Thread-0 and i is :3
Current thread is:Thread-0 and i is :4
Current thread is:Thread-0 and i is :5
Current thread is:Thread-0 and i is :6
Current thread is:Thread-0 and i is :7
Current thread is:Thread-0 and i is :8
Current thread is:Thread-0 and i is :9
Current thread is:Thread-0 and i is :10
Current thread is:Thread-0 and i is :11
Current thread is:Thread-0 and i is :12
Current thread is:Thread-0 and i is :13
Current thread is:Thread-0 and i is :14
Current thread is:Thread-0 and i is :15
Current thread is:Thread-0 and i is :16
Current thread is:Thread-0 and i is :17
Current thread is:Thread-0 and i is :18
Current thread is:Thread-0 and i is :19
Current thread is:Thread-0 and i is :20
Current thread is:Thread-0 and i is :21
Current thread is:Thread-0 and i is :22
Current thread is:Thread-0 and i is :23
Current thread is:Thread-0 and i is :24
Current thread is:Thread-0 and i is :25
Current thread is:Thread-0 and i is :26
Current thread is:Thread-0 and i is :27
Current thread is:Thread-0 and i is :28
Current thread is:Thread-0 and i is :29
Current thread is:Thread-0 and i is :30
Current thread is:Thread-0 and i is :31
Current thread is:Thread-0 and i is :32
Current thread is:Thread-0 and i is :33
Current thread is:Thread-0 and i is :34
Current thread is:Thread-0 and i is :35
Current thread is:Thread-0 and i is :36
Current thread is:Thread-0 and i is :37
Current thread is:Thread-0 and i is :38
Current thread is:Thread-0 and i is :39
Current thread is:Thread-0 and i is :40
Current thread is:Thread-0 and i is :41
Current thread is:Thread-0 and i is :42
Current thread is:Thread-0 and i is :43
Current thread is:Thread-0 and i is :44
Current thread is:Thread-0 and i is :45
Current thread is:Thread-0 and i is :46
Current thread is:Thread-0 and i is :47
Current thread is:Thread-0 and i is :48
Current thread is:Thread-0 and i is :49
Current thread is:Thread-0 and i is :50

 

在上述实例中,我们可以看到synchronized用于修饰普通方法,所以该锁为对象锁,也就是如果我现在再new  ThreadSynchronized()对象的话他将获得一把新的锁和原来的thread-0没有一点关系,他们将各自干各自的事情。

论证:

package com.springboot.thread;

public class ThreadSynchronized extends Thread{
    private int i=0;

    @Override
    public void run() {
       addI();
    }

    public synchronized void addI(){
        while (i<=50){
            System.out.println("Current thread is:"+Thread.currentThread().getName()+" and i is :"+i);
            i++;
        }
    }
}

class TestThread{
    public static void main(String[] args) {
        ThreadSynchronized threadSynchronized = new ThreadSynchronized();
        ThreadSynchronized threadSynchronized1 = new ThreadSynchronized();
        threadSynchronized.start();
        threadSynchronized1.start();
    }
}

运行结果:

Current thread is:Thread-1 and i is :0
Current thread is:Thread-1 and i is :1
Current thread is:Thread-1 and i is :2
Current thread is:Thread-1 and i is :3
Current thread is:Thread-1 and i is :4
Current thread is:Thread-1 and i is :5
Current thread is:Thread-1 and i is :6
Current thread is:Thread-1 and i is :7
Current thread is:Thread-1 and i is :8
Current thread is:Thread-1 and i is :9
Current thread is:Thread-1 and i is :10
Current thread is:Thread-1 and i is :11
Current thread is:Thread-1 and i is :12
Current thread is:Thread-1 and i is :13
Current thread is:Thread-1 and i is :14
Current thread is:Thread-1 and i is :15
Current thread is:Thread-1 and i is :16
Current thread is:Thread-1 and i is :17
Current thread is:Thread-1 and i is :18
Current thread is:Thread-1 and i is :19
Current thread is:Thread-1 and i is :20
Current thread is:Thread-1 and i is :21
Current thread is:Thread-1 and i is :22
Current thread is:Thread-1 and i is :23
Current thread is:Thread-1 and i is :24
Current thread is:Thread-1 and i is :25
Current thread is:Thread-1 and i is :26
Current thread is:Thread-1 and i is :27
Current thread is:Thread-1 and i is :28
Current thread is:Thread-1 and i is :29
Current thread is:Thread-1 and i is :30
Current thread is:Thread-1 and i is :31
Current thread is:Thread-1 and i is :32
Current thread is:Thread-1 and i is :33
Current thread is:Thread-1 and i is :34
Current thread is:Thread-1 and i is :35
Current thread is:Thread-1 and i is :36
Current thread is:Thread-1 and i is :37
Current thread is:Thread-1 and i is :38
Current thread is:Thread-1 and i is :39
Current thread is:Thread-1 and i is :40
Current thread is:Thread-1 and i is :41
Current thread is:Thread-1 and i is :42
Current thread is:Thread-1 and i is :43
Current thread is:Thread-1 and i is :44
Current thread is:Thread-1 and i is :45
Current thread is:Thread-1 and i is :46
Current thread is:Thread-1 and i is :47
Current thread is:Thread-1 and i is :48
Current thread is:Thread-1 and i is :49
Current thread is:Thread-1 and i is :50
Current thread is:Thread-0 and i is :0
Current thread is:Thread-0 and i is :1
Current thread is:Thread-0 and i is :2
Current thread is:Thread-0 and i is :3
Current thread is:Thread-0 and i is :4
Current thread is:Thread-0 and i is :5
Current thread is:Thread-0 and i is :6
Current thread is:Thread-0 and i is :7
Current thread is:Thread-0 and i is :8
Current thread is:Thread-0 and i is :9
Current thread is:Thread-0 and i is :10
Current thread is:Thread-0 and i is :11
Current thread is:Thread-0 and i is :12
Current thread is:Thread-0 and i is :13
Current thread is:Thread-0 and i is :14
Current thread is:Thread-0 and i is :15
Current thread is:Thread-0 and i is :16
Current thread is:Thread-0 and i is :17
Current thread is:Thread-0 and i is :18
Current thread is:Thread-0 and i is :19
Current thread is:Thread-0 and i is :20
Current thread is:Thread-0 and i is :21
Current thread is:Thread-0 and i is :22
Current thread is:Thread-0 and i is :23
Current thread is:Thread-0 and i is :24
Current thread is:Thread-0 and i is :25
Current thread is:Thread-0 and i is :26
Current thread is:Thread-0 and i is :27
Current thread is:Thread-0 and i is :28
Current thread is:Thread-0 and i is :29
Current thread is:Thread-0 and i is :30
Current thread is:Thread-0 and i is :31
Current thread is:Thread-0 and i is :32
Current thread is:Thread-0 and i is :33
Current thread is:Thread-0 and i is :34
Current thread is:Thread-0 and i is :35
Current thread is:Thread-0 and i is :36
Current thread is:Thread-0 and i is :37
Current thread is:Thread-0 and i is :38
Current thread is:Thread-0 and i is :39
Current thread is:Thread-0 and i is :40
Current thread is:Thread-0 and i is :41
Current thread is:Thread-0 and i is :42
Current thread is:Thread-0 and i is :43
Current thread is:Thread-0 and i is :44
Current thread is:Thread-0 and i is :45
Current thread is:Thread-0 and i is :46
Current thread is:Thread-0 and i is :47
Current thread is:Thread-0 and i is :48
Current thread is:Thread-0 and i is :49
Current thread is:Thread-0 and i is :50

从运行结果可以看出,我们的结论正确,他确实是各自拿到各自的锁干各自的事。

那如果我们像让这两个对象共竞争同一把锁,我们应该怎么做呢?

     引出类锁。

(2).synchronized修饰静态方法

package com.springboot.thread;

public class ThreadSynchronized extends Thread{
    private static int i=0;

    @Override
    public void run() {
       addI();
    }

    public static synchronized void addI(){
        while (i<=50){
            System.out.println("Current thread is:"+Thread.currentThread().getName()+" and i is :"+i);
            i++;
        }
    }
}

class TestThread{
    public static void main(String[] args) {
        ThreadSynchronized threadSynchronized = new ThreadSynchronized();
        ThreadSynchronized threadSynchronized1 = new ThreadSynchronized();
        threadSynchronized.start();
        threadSynchronized1.start();
    }
}

运行结果如下:

Current thread is:Thread-0 and i is :0
Current thread is:Thread-0 and i is :1
Current thread is:Thread-0 and i is :2
Current thread is:Thread-0 and i is :3
Current thread is:Thread-0 and i is :4
Current thread is:Thread-0 and i is :5
Current thread is:Thread-0 and i is :6
Current thread is:Thread-0 and i is :7
Current thread is:Thread-0 and i is :8
Current thread is:Thread-0 and i is :9
Current thread is:Thread-0 and i is :10
Current thread is:Thread-0 and i is :11
Current thread is:Thread-0 and i is :12
Current thread is:Thread-0 and i is :13
Current thread is:Thread-0 and i is :14
Current thread is:Thread-0 and i is :15
Current thread is:Thread-0 and i is :16
Current thread is:Thread-0 and i is :17
Current thread is:Thread-0 and i is :18
Current thread is:Thread-0 and i is :19
Current thread is:Thread-0 and i is :20
Current thread is:Thread-0 and i is :21
Current thread is:Thread-0 and i is :22
Current thread is:Thread-0 and i is :23
Current thread is:Thread-0 and i is :24
Current thread is:Thread-0 and i is :25
Current thread is:Thread-0 and i is :26
Current thread is:Thread-0 and i is :27
Current thread is:Thread-0 and i is :28
Current thread is:Thread-0 and i is :29
Current thread is:Thread-0 and i is :30
Current thread is:Thread-0 and i is :31
Current thread is:Thread-0 and i is :32
Current thread is:Thread-0 and i is :33
Current thread is:Thread-0 and i is :34
Current thread is:Thread-0 and i is :35
Current thread is:Thread-0 and i is :36
Current thread is:Thread-0 and i is :37
Current thread is:Thread-0 and i is :38
Current thread is:Thread-0 and i is :39
Current thread is:Thread-0 and i is :40
Current thread is:Thread-0 and i is :41
Current thread is:Thread-0 and i is :42
Current thread is:Thread-0 and i is :43
Current thread is:Thread-0 and i is :44
Current thread is:Thread-0 and i is :45
Current thread is:Thread-0 and i is :46
Current thread is:Thread-0 and i is :47
Current thread is:Thread-0 and i is :48
Current thread is:Thread-0 and i is :49
Current thread is:Thread-0 and i is :50

当然这只是一种情况,但无论是哪种情况都能保证两个对象竞争同一把锁,任何时候只有一个线程能执行synchronized所修饰的方法,也从侧面说明了该锁是类级别的。

(3)synchronized修饰非静态代码块

public class ThreadSynchronized extends Thread{
    private int i=0;

    @Override
    public void run() {
        /*this指代当前实例对象*/
        synchronized(this){
            while (i<=50){
                System.out.println("Current thread is:"+Thread.currentThread().getName()+" and i is :"+i);
                i++;
            }
        }
    }
}

class TestThread{
    public static void main(String[] args) {
        ThreadSynchronized threadSynchronized = new ThreadSynchronized();
        ThreadSynchronized threadSynchronized1 = new ThreadSynchronized();
        threadSynchronized.start();
        threadSynchronized1.start();
    }
}

运行结果:

Current thread is:Thread-0 and i is :0
Current thread is:Thread-0 and i is :1
Current thread is:Thread-0 and i is :2
Current thread is:Thread-0 and i is :3
Current thread is:Thread-0 and i is :4
Current thread is:Thread-0 and i is :5
Current thread is:Thread-0 and i is :6
Current thread is:Thread-0 and i is :7
Current thread is:Thread-0 and i is :8
Current thread is:Thread-0 and i is :9
Current thread is:Thread-0 and i is :10
Current thread is:Thread-0 and i is :11
Current thread is:Thread-0 and i is :12
Current thread is:Thread-0 and i is :13
Current thread is:Thread-0 and i is :14
Current thread is:Thread-0 and i is :15
Current thread is:Thread-0 and i is :16
Current thread is:Thread-0 and i is :17
Current thread is:Thread-0 and i is :18
Current thread is:Thread-0 and i is :19
Current thread is:Thread-0 and i is :20
Current thread is:Thread-0 and i is :21
Current thread is:Thread-0 and i is :22
Current thread is:Thread-0 and i is :23
Current thread is:Thread-0 and i is :24
Current thread is:Thread-0 and i is :25
Current thread is:Thread-0 and i is :26
Current thread is:Thread-0 and i is :27
Current thread is:Thread-0 and i is :28
Current thread is:Thread-0 and i is :29
Current thread is:Thread-0 and i is :30
Current thread is:Thread-0 and i is :31
Current thread is:Thread-0 and i is :32
Current thread is:Thread-0 and i is :33
Current thread is:Thread-0 and i is :34
Current thread is:Thread-0 and i is :35
Current thread is:Thread-0 and i is :36
Current thread is:Thread-0 and i is :37
Current thread is:Thread-0 and i is :38
Current thread is:Thread-0 and i is :39
Current thread is:Thread-0 and i is :40
Current thread is:Thread-0 and i is :41
Current thread is:Thread-0 and i is :42
Current thread is:Thread-0 and i is :43
Current thread is:Thread-0 and i is :44
Current thread is:Thread-0 and i is :45
Current thread is:Thread-0 and i is :46
Current thread is:Thread-0 and i is :47
Current thread is:Thread-0 and i is :48
Current thread is:Thread-0 and i is :49
Current thread is:Thread-0 and i is :50
Current thread is:Thread-1 and i is :0
Current thread is:Thread-1 and i is :1
Current thread is:Thread-1 and i is :2
Current thread is:Thread-1 and i is :3
Current thread is:Thread-1 and i is :4
Current thread is:Thread-1 and i is :5
Current thread is:Thread-1 and i is :6
Current thread is:Thread-1 and i is :7
Current thread is:Thread-1 and i is :8
Current thread is:Thread-1 and i is :9
Current thread is:Thread-1 and i is :10
Current thread is:Thread-1 and i is :11
Current thread is:Thread-1 and i is :12
Current thread is:Thread-1 and i is :13
Current thread is:Thread-1 and i is :14
Current thread is:Thread-1 and i is :15
Current thread is:Thread-1 and i is :16
Current thread is:Thread-1 and i is :17
Current thread is:Thread-1 and i is :18
Current thread is:Thread-1 and i is :19
Current thread is:Thread-1 and i is :20
Current thread is:Thread-1 and i is :21
Current thread is:Thread-1 and i is :22
Current thread is:Thread-1 and i is :23
Current thread is:Thread-1 and i is :24
Current thread is:Thread-1 and i is :25
Current thread is:Thread-1 and i is :26
Current thread is:Thread-1 and i is :27
Current thread is:Thread-1 and i is :28
Current thread is:Thread-1 and i is :29
Current thread is:Thread-1 and i is :30
Current thread is:Thread-1 and i is :31
Current thread is:Thread-1 and i is :32
Current thread is:Thread-1 and i is :33
Current thread is:Thread-1 and i is :34
Current thread is:Thread-1 and i is :35
Current thread is:Thread-1 and i is :36
Current thread is:Thread-1 and i is :37
Current thread is:Thread-1 and i is :38
Current thread is:Thread-1 and i is :39
Current thread is:Thread-1 and i is :40
Current thread is:Thread-1 and i is :41
Current thread is:Thread-1 and i is :42
Current thread is:Thread-1 and i is :43
Current thread is:Thread-1 and i is :44
Current thread is:Thread-1 and i is :45
Current thread is:Thread-1 and i is :46
Current thread is:Thread-1 and i is :47
Current thread is:Thread-1 and i is :48
Current thread is:Thread-1 and i is :49
Current thread is:Thread-1 and i is :50

结果同synchronized修饰普通方法,解释自然也和synchronized修饰普通方法一样,不多赘述。

插曲:

public class ThreadSynchronized extends Thread{
    private static int i=0;

    @Override
    public void run() {
        /*this指代当前实例对象*/
        synchronized(this){
            while (i<=50){
                System.out.println("Current thread is:"+Thread.currentThread().getName()+" and i is :"+i);
                i++;
            }
        }
    }
}

class TestThread{
    public static void main(String[] args) {
        ThreadSynchronized threadSynchronized = new ThreadSynchronized();
        ThreadSynchronized threadSynchronized1 = new ThreadSynchronized();
        threadSynchronized.start();
        threadSynchronized1.start();
    }
}

运行结果:

Current thread is:Thread-1 and i is :0
Current thread is:Thread-1 and i is :1
Current thread is:Thread-1 and i is :2
Current thread is:Thread-1 and i is :3
Current thread is:Thread-1 and i is :4
Current thread is:Thread-1 and i is :5
Current thread is:Thread-1 and i is :6
Current thread is:Thread-1 and i is :7
Current thread is:Thread-1 and i is :8
Current thread is:Thread-1 and i is :9
Current thread is:Thread-1 and i is :10
Current thread is:Thread-1 and i is :11
Current thread is:Thread-1 and i is :12
Current thread is:Thread-1 and i is :13
Current thread is:Thread-1 and i is :14
Current thread is:Thread-1 and i is :15
Current thread is:Thread-1 and i is :16
Current thread is:Thread-1 and i is :17
Current thread is:Thread-1 and i is :18
Current thread is:Thread-1 and i is :19
Current thread is:Thread-1 and i is :20
Current thread is:Thread-1 and i is :21
Current thread is:Thread-1 and i is :22
Current thread is:Thread-1 and i is :23
Current thread is:Thread-1 and i is :24
Current thread is:Thread-1 and i is :25
Current thread is:Thread-1 and i is :26
Current thread is:Thread-1 and i is :27
Current thread is:Thread-1 and i is :28
Current thread is:Thread-1 and i is :29
Current thread is:Thread-1 and i is :30
Current thread is:Thread-1 and i is :31
Current thread is:Thread-1 and i is :32
Current thread is:Thread-1 and i is :33
Current thread is:Thread-1 and i is :34
Current thread is:Thread-1 and i is :35
Current thread is:Thread-1 and i is :36
Current thread is:Thread-1 and i is :37
Current thread is:Thread-0 and i is :0
Current thread is:Thread-0 and i is :39
Current thread is:Thread-0 and i is :40
Current thread is:Thread-0 and i is :41
Current thread is:Thread-0 and i is :42
Current thread is:Thread-0 and i is :43
Current thread is:Thread-0 and i is :44
Current thread is:Thread-0 and i is :45
Current thread is:Thread-0 and i is :46
Current thread is:Thread-0 and i is :47
Current thread is:Thread-0 and i is :48
Current thread is:Thread-0 and i is :49
Current thread is:Thread-1 and i is :38
Current thread is:Thread-0 and i is :50

乍一看,你肯定会说“卧槽,你特么仿佛在逗我,一样的代码运行结果却差距之大!我感觉你特么就在忽悠人!”

calm down!你仔细观察我在  private static int i=0;这里动了手脚,在这里加了一个static,那为什么加了static之后结果会变成这样呢?

如果你有java开发经验或者你系统学习过java基础知识应该知道,当我们用static修饰一个类、方法、代码块等时,他是从属于类的,在编译阶段已经被加载到java虚拟机,不需要创建对象就能被调用。(博客太长怕你看了前面忘了后面,故再抄一遍)

所以,当编译上述实例的时候int i=0;已经被加载到虚拟机,所以当执行到 threadSynchronized.start();时候拿到i=0,然后thread-0开始一顿操作猛如虎疯狂做加法操作。同时主线程继续执行threadSynchronized1.start(); 然后thread-1也去获取i,然后拿到i还是等于0。这时候你可能会说,这怎么可能?你不是说static修饰的变量是从属于类的吗?那么我看thread-0都已经将i加到37了,thread-1应该拿到37然后做完++操作以后应该是38才对。

我想说:“static修饰的变量是从属于类”这段话是书上说的,我不负责任。【Just Kidding!!】

其实是这样的:i++ 和i=i+1;是一个意思,这就说明i++是个非原子操作,i要先加一然后再赋值。i做加一操作是要花费时间的,所以有如下一种情况:当thread-0正在做加一操作还没结束的时候thread-1闯了进来,拿到i当前的值自然就是0 啦,所以出现上述那样的现象。同时你也可以看到虽然thread-1在后面输出了i=38,但是thread-0在前却是从39开始做加一操作。

至此,我们对static与synchronized的理解又进了一步。

 

(4)如果我们想将上述实例中所用的代码变成线程安全的,我们应该如何写呢?

package com.springboot.thread;

public class ThreadSynchronized extends Thread{
    private static int i=0;


    @Override
    public void run() {
          /*类锁*/
          synchronized(ThreadSynchronized.class) {
            while (i<=50){
                System.out.println("Current thread is:"+Thread.currentThread().getName()+" and i is :"+i);
                i++;
            }
        }
    }
}

class TestThread{
    public static void main(String[] args) {
        ThreadSynchronized  threadSynchronized = new ThreadSynchronized();
        ThreadSynchronized threadSynchronized1 = new ThreadSynchronized();
        threadSynchronized.start();
        threadSynchronized1.start();
    }
}

简单做一下解释:这里能实现线程安全的关键在于在 synchronized(ThreadSynchronized.class)这一行代码与 private static int i=0;的共同作用结果,具体原因相信如果认真研究了上面的实例加解释应该就明白了。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值