爱编程,爱生活

Java concurrent synchronized 关键字

2018-06-16  本文已影响18人  熬夜的猫头鹰

Java concurrent synchronized 关键字解析

synchronized是Java中的关键字,是一种同步锁。它修饰的对象有以下几种:

修饰代码块DEMO

public class Account {

        public void synchronizedMethod() throws InterruptedException {
            synchronized (this) {
                Thread.sleep(1000);
                //todo

            }
        }


        public void unSynchronizedMethod() {
            //todo
            System.err.println("I am not a sync thread,my thread name is " + Thread.currentThread().getName());

        }
    }

修饰代码块时,被修饰的部分在同一时间点只能有一个线程A进入,也就是说一个线程A已经进入Account一个实例 类的方法 synchronizedMethod,那么如果有其他的一个线程B此时想要访问 同一个 Account实例的 synchronizedMethod方法,必须等待已经完成的线程A执行完里边同步的代码块。线程B才能进入同步的代码块;但是如果线程B访问的是 unSynchronizedMethod,那么则不需要等待。

注意 一定是同个Account实例,如果是不同的实例,则没有等待。

修饰方法DEMO

public class Account {

        public synchronized void synchronizedMethod() throws InterruptedException {
            //Thread.sleep(1000);
            //todo

        }


        public void unSynchronizedMethod() {
            //todo
            System.err.println("I am not a sync thread,my thread name is " + Thread.currentThread().getName());

        }
    }
    

修饰方法和修饰代码块是一样的,只不过两个的同步的作用域是不同的,修饰方法作用域是整个方法,如果修饰的是代码块,则只是对代码块里边的代码进行同步。

修饰静态方法

/**
 * Created by Jeffy on 17/5/20.
 */
public class Account {

    public static synchronized void synchronizedMethod() throws InterruptedException {
        System.err.println(Thread.currentThread().getName() + " is visiting this method");
        Thread.sleep(5000);
        //todo


    }


    public void unSynchronizedMethod() {
        //todo
        System.err.println("I am not a sync thread,my thread name is " + Thread.currentThread().getName());

    }
}

测试类


/**
 * Created by Jeffy on 17/5/20.
 */
public class SynchronizedMain {

    public static void main(String[] args) throws InterruptedException {
        new Thread(new Thread1(new Account()),"thread1").start();
        new Thread(new Thread2(new Account()),"thread2").start();

    }

    static class Thread1 implements Runnable{

        private Account account;

        public Thread1(Account account) {
            this.account = account;
        }

        @Override
        public void run() {
            try {
                account.synchronizedMethod();
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }


    static class Thread2 implements Runnable{

        private Account account;

        public Thread2(Account account) {
            this.account = account;
        }

        @Override
        public void run() {
            try {
                account.synchronizedMethod();
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }

}

输出

thread1 is visiting this method
thread2 is visiting this method

结果解释,你会发现 thread1 is visiting this method 打印完之后大概用了5秒钟之后 thread2 is visiting this method 才打印出来,说明synchronized修饰的静态方法,同步的是这个Account的所有对象。而并非某一对象。

修饰类

public class Account {

    public void synchronizedMethod() throws InterruptedException {
        synchronized (this.getClass()) {
            System.err.println(Thread.currentThread().getName() + " is visiting this method");
            Thread.sleep(5000);
            //todo

        }
    }


    public void unSynchronizedMethod() {
        //todo
        System.err.println("I am not a sync thread,my thread name is " + Thread.currentThread().getName());

    }
}

修饰的效果和修饰静态的方法是一样的,同步的是这个类的所有对象,并非某一个具体的实例。

synchronized关键字注意事项

上一篇 下一篇

猜你喜欢

热点阅读