Java中使用synchronized多线程同步的实例

synchronized关键字

Java提供了synchronized关键字,用于控制台多线程同步。
可以加在方法上,在方法名前加synchronized
也可以加在一段代码块,synchronized (xxx) { ... },其中xxx为对象,一般为this, Xxx.class或者某个对象实例。

实例1

import java.util.concurrent.ThreadLocalRandom;
import java.util.concurrent.TimeUnit;

/**
 * synchronized非static方法,多线程不同对象访问
 * 并未同步执行
 * 因为MyThread的run方法中new了不同的MySync对象
 *
 * @author cdfive
 */
public class SynchoronizedDemo1 {

    public static void main(String[] args) {
        int threadNum = 3;
        for (int i = 0; i < threadNum; i++) {
            MyThread myThread = new MyThread();
            myThread.start();
        }
    }

    static class MySync {

        public synchronized void test() {
            long start = System.currentTimeMillis();
            System.out.println(String.format("%s start", Thread.currentThread().getName()));
            try {
                TimeUnit.SECONDS.sleep(ThreadLocalRandom.current().nextInt(3));
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            System.out.println(String.format("%s end,cost=%dms", Thread.currentThread().getName(), (System.currentTimeMillis() - start)));
        }
    }

    static class MyThread extends Thread {

        @Override
        public void run() {
            MySync sync = new MySync();
            sync.test();
        }
    }
}

实例2

import java.util.concurrent.ThreadLocalRandom;
import java.util.concurrent.TimeUnit;

/**
 * 在非static方法里的synchronized this,多线程不同对象访问
 * 并未同步执行
 * 跟SynchoronizedDemo1类似,因为MyThread的run方法中new了不同的MySync对象
 *
 * @author cdfive
 */
public class SynchoronizedDemo2 {

    public static void main(String[] args) {
        int threadNum = 3;
        for (int i = 0; i < threadNum; i++) {
            MyThread myThread = new MyThread();
            myThread.start();
        }
    }

    static class MySync {

        public void test() {
            synchronized (this) {
                long start = System.currentTimeMillis();
                System.out.println(String.format("%s start", Thread.currentThread().getName()));
                try {
                    TimeUnit.SECONDS.sleep(ThreadLocalRandom.current().nextInt(3));
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                System.out.println(String.format("%s end,cost=%dms", Thread.currentThread().getName(), (System.currentTimeMillis() - start)));
            }
        }
    }

    static class MyThread extends Thread {

        @Override
        public void run() {
            MySync sync = new MySync();
            sync.test();
        }
    }
}

实例3

import java.util.concurrent.ThreadLocalRandom;
import java.util.concurrent.TimeUnit;

/**
 * synchronized非static方法,多线程相同对象访问
 * 同步执行成功
 *
 * @author cdfive
 */
public class SynchoronizedDemo3 {

    public static void main(String[] args) {
        int threadNum = 3;
        MySync mySync = new MySync();
        for (int i = 0; i < threadNum; i++) {
            MyThread myThread = new MyThread(mySync);
            myThread.start();
        }
    }

    static class MySync {

        public synchronized void test() {
            long start = System.currentTimeMillis();
            System.out.println(String.format("%s start", Thread.currentThread().getName()));
            try {
                TimeUnit.SECONDS.sleep(ThreadLocalRandom.current().nextInt(3));
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            System.out.println(String.format("%s end,cost=%dms", Thread.currentThread().getName(), (System.currentTimeMillis() - start)));
        }
    }

    static class MyThread extends Thread {

        private MySync mySync;

        public MyThread(MySync mySync) {
            this.mySync = mySync;
        }

        @Override
        public void run() {
            mySync.test();
        }
    }
}

实例4

/**
 * 在非static方法里的synchronized this,多线程相同对象访问
 * 同步执行成功
 *
 * @author cdfive
 */
public class SynchoronizedDemo4 {

    public static void main(String[] args) {
        int threadNum = 3;
        MySync mySync = new MySync();
        for (int i = 0; i < threadNum; i++) {
            MyThread myThread = new MyThread(mySync);
            myThread.start();
        }
    }

    static class MySync {

        public synchronized void test() {
            long start = System.currentTimeMillis();
            System.out.println(String.format("%s start", Thread.currentThread().getName()));
            try {
                TimeUnit.SECONDS.sleep(ThreadLocalRandom.current().nextInt(3));
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            System.out.println(String.format("%s end,cost=%dms", Thread.currentThread().getName(), (System.currentTimeMillis() - start)));
        }
    }

    static class MyThread extends Thread {

        private MySync mySync;

        public MyThread(MySync mySync) {
            this.mySync = mySync;
        }

        @Override
        public void run() {
            mySync.test();
        }
    }
}

实例5

import java.util.concurrent.ThreadLocalRandom;
import java.util.concurrent.TimeUnit;

/**
 * 在非static方法里的synchronized Xxx.class,多线程不同对象访问
 * 同步执行成功
 * synchronized Xxx.class相当于全局锁
 *
 * @author cdfive
 */
public class SynchoronizedDemo5 {

    public static void main(String[] args) {
        int threadNum = 3;
        for (int i = 0; i < threadNum; i++) {
            MyThread myThread = new MyThread();
            myThread.start();
        }
    }

    static class MySync {

        public void test() {
            synchronized (SynchoronizedDemo5.class) {
                long start = System.currentTimeMillis();
                System.out.println(String.format("%s start", Thread.currentThread().getName()));
                try {
                    TimeUnit.SECONDS.sleep(ThreadLocalRandom.current().nextInt(3));
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                System.out.println(String.format("%s end,cost=%dms", Thread.currentThread().getName(), (System.currentTimeMillis() - start)));
            }
        }
    }

    static class MyThread extends Thread {

        @Override
        public void run() {
            MySync sync = new MySync();
            sync.test();
        }
    }
}

以上实例synchronized同步方法,this,Xxx.class时,多线程使用相同或不同对象访问,有不同的结果,在日常开发中需要注意。

posted @ 2021-01-13 21:44  cdfive  阅读(317)  评论(0编辑  收藏  举报