synchronized

针对线程的安全问题,可以使用synchronized解决:

public class Outputter {

    //方法1,用synchronized修饰代码块
    // 这个方法锁住的是多线程之间共享的对象
    /*public void output(String str){
        synchronized (this){
            for(int  i = 0; i < str.length();i++){
                System.out.print(str.charAt(i));
            }
        }
    }*/

    //方法2,用synchronized修饰方法
    //这个方法是用synchronized锁住整个方法
    public synchronized void output(String str){
            for(int  i = 0; i < str.length();i++){
                System.out.print(str.charAt(i));
            }
    }
    
    /**
     * 需要注意的是,synchronized会造成线程死锁
     */
    
}
public class TraditionalThreadSynchronized {

    public static void main(String[] args) {
        final Outputter outputter = new Outputter();
        new Thread("Thread1"){
            public void run(){
                outputter.output("zhangsanlisi ");
            }
        }.start();

        new Thread("Thread2"){
            public void run(){
                outputter.output("Chinaese ");
            }
        }.start();

        new Thread("Thread3"){
            public void run(){
                outputter.output("American ");
            }
        }.start();

        new Thread("Thread4"){
            public void run(){
                outputter.output("abcdefghijklmn ");
            }
        }.start();

        new Thread("Thread5"){
            public void run(){
                outputter.output("abcdefghijklmn ");
            }
        }.start();

    }
}

 synchronized讲解:

  每个锁被称为monitor,有两个队列:就绪队列,阻塞队列。

  就绪队列存储了将要获得锁的线程,阻塞队列存储了被阻塞的线程,当一个线程被唤醒notify后,就进入就绪队列,反之被wait后,就进入了阻塞队列。

  一个线程执行互斥代码的过程是:

  1. 获得同步锁

  2. 清空工作内存

  3. 从主内存中拷贝对象副本到工作内存

  4. 执行代码

  5. 刷新主内存

  6. 释放同步锁

所以,synchronized保证了线程的有序性和可见性。

原文地址:https://www.cnblogs.com/lfdingye/p/7443208.html