java同步机制对象锁使用方式比较

来源:互联网 发布:三国志13 知乎 编辑:程序博客网 时间:2024/05/16 11:07


class Sync {    private byte[] lock = new byte[0];    public void sync() throws InterruptedException {        synchronized (lock) {            runThread();        }    }    public void thisSync() throws InterruptedException {        synchronized (this) {            runThread();        }    }    public synchronized static void staticSync() throws InterruptedException { // 同步的static 函数        runThread();    }    public void classSync() throws InterruptedException { //        synchronized (Sync.class) {            runThread();        }    }    private static void runThread() throws InterruptedException {        Thread current = Thread.currentThread();        System.out.println("current thread id:" + current.getId() + "enter...");        System.out.println("1111");        Thread.sleep(1000);        System.out.println("2222");        Thread.sleep(1000);        System.out.println("3333");        Thread.sleep(1000);        System.out.println("4444");        Thread.sleep(1000);        System.out.println("5555");        System.out.println("current thread id:" + current.getId() + "out...");    }}




1.同一个线程lock对象锁是否可复用(即不用等待)

结论:可复用

public class TestObjectSyncLock {    private static byte[] lock = new byte[0];//零长度的byte数组对象创建起来将比任何对象都经济――查看编译后的字节码:生成零长度的byte[]对象只需3条操作码,而Object lock = new Object()则需要7行操作码。     public static void main(String[] args) throws InterruptedException {    //1.同一个线程lock对象锁是否可复用(即不用等待)----可复用                synchronized (lock) {            new Thread(new Runnable() {                public void run() {                    try {                        Thread.sleep(3000);                    } catch (InterruptedException e) {                        e.printStackTrace();                    }                    System.out.println("aaa");                }            }).start();            // lock.notify();        }        synchronized (lock) {            System.out.println("bbb");            // lock.wait();        }   }}

结果:

bbb
aaa

2.同一个对象,多线程访问(一个主线程,一个新开线程)

结论:锁有效

  Thread current = Thread.currentThread();         System.out.println("current thread id:"+current.getId()+"start...");       final Sync sync =new Sync();               new Thread(new Runnable() {                        public void run() {                Thread current = Thread.currentThread();                  System.out.println("current thread id:"+current.getId()+"start...");                try {                    sync.sync();                } catch (InterruptedException e) {                    e.printStackTrace();                }                              }        }).start();                sync.sync();

结果:

current thread id:1start...
current thread id:1enter...
1111
current thread id:9start...
2222
3333
4444
5555
current thread id:1out...
current thread id:9enter...
1111
2222
3333
4444
5555
current thread id:9out...


3.不同对象,多线程访问

结论:锁无效


 Thread current = Thread.currentThread();        System.out.println("currret thread id:" + current.getId() + "start...");        final Sync sync = new Sync();        final Sync sync2 = new Sync();        new Thread(new Runnable() {            public void run() {                Thread current = Thread.currentThread();                System.out.println("currret thread id:" + current.getId() + "start...");                try {                    sync2.sync();                } catch (InterruptedException e) {                    e.printStackTrace();                }            }        }).start();        sync.sync();

结果:

currret thread id:1start...
current thread id:1enter...
1111
currret thread id:9start...
current thread id:9enter...
1111
2222
2222
3333
3333
4444
4444
5555
current thread id:1out...
5555
current thread id:9out...


4.wait(),notify()----调用wait或notify时,该线程必须是该对象锁的所有者,否则会抛出Exception in thread "Thread-0" java.lang.IllegalMonitorStateException

 new Thread(new Runnable() {            public void run() {                System.out.println("------");                synchronized (lock) {                    try {                        Thread.sleep(3000);                    } catch (InterruptedException e) {                        e.printStackTrace();                    }                    lock.notify();                    System.out.println(" after notify ...");                }            }        }).start();        synchronized (lock) {            System.out.println("enter ...");            lock.wait();            System.out.println("out ...");        }

结果:

enter ...
------
 after notify ...
out ...


5.wait(),notifyAll()----notifyAll()唤醒所有正在wait的不同线程

    new Thread(new Runnable() {            public void run() {                synchronized (lock) {                    System.out.println("enter thread 1 ...");                    try {                        lock.wait();                    } catch (InterruptedException e) {                        e.printStackTrace();                    }                    System.out.println("leave thread 1 ...");                }            }        }).start();        new Thread(new Runnable() {            public void run() {                synchronized (lock) {                    System.out.println("enter thread 2 ...");                    try {                        lock.wait();                    } catch (InterruptedException e) {                        e.printStackTrace();                    }                    System.out.println("leave thread 2 ...");                }            }        }).start();        new Thread(new Runnable() {            public void run() {                System.out.println("------");                synchronized (lock) {                    try {                        Thread.sleep(3000);                    } catch (InterruptedException e) {                        e.printStackTrace();                    }                    lock.notifyAll();// notifyAll方法会唤醒所有正在等待对象控制权的线程。                    // lock.notify();//随机通知一个正在等待的线程                    System.out.println("after notifyAll ...");                }            }        }).start();

结果:

enter thread 1 ...
enter thread 2 ...
------
after notifyAll ...
leave thread 2 ...
leave thread 1 ...

6.static 同步方法,不同对象

 Thread current = Thread.currentThread();        System.out.println("currret thread id:" + current.getId() + "start...");        Sync sync = new Sync();        new Thread(new Runnable() {            public void run() {                Sync sync = new Sync();                Thread current = Thread.currentThread();                System.out.println("currret thread id:" + current.getId() + "start...");                try {                    sync.staticSync();// 锁有效                    // Sync.staticSync();//锁有效                    // sync.sync();//锁无效                } catch (InterruptedException e) {                    e.printStackTrace();                }            }        }).start();        sync.staticSync();// 锁有效        // Sync.staticSync();//锁有效        // sync.sync();//锁无效

结果:

currret thread id:1start...
current thread id:1enter...
1111
currret thread id:9start...
2222
3333
4444
5555
current thread id:1out...
current thread id:9enter...
1111
2222
3333
4444
5555
current thread id:9out...

7.class 同步方法,不同对象


 Thread current = Thread.currentThread();        System.out.println("currret thread id:" + current.getId() + "start...");        Sync sync = new Sync();        new Thread(new Runnable() {            public void run() {                Sync sync = new Sync();                Thread current = Thread.currentThread();                System.out.println("currret thread id:" + current.getId() + "start...");                try {                    sync.classSync();// 锁有效                } catch (InterruptedException e) {                    e.printStackTrace();                }            }        }).start();        sync.classSync();// 锁有效

结果:

currret thread id:1start...
current thread id:1enter...
1111
currret thread id:9start...
2222
3333
4444
5555
current thread id:1out...
current thread id:9enter...
1111
2222
3333
4444
5555
current thread id:9out...

8.this 同步方法,不同对象,跟2一样,对象锁

  final Sync sync = new Sync();        new Thread(new Runnable() {            public void run() {                // Sync sync =new Sync();                Thread current = Thread.currentThread();                System.out.println("currret thread id:" + current.getId() + "start...");                try {                    sync.thisSync();                } catch (InterruptedException e) {                    e.printStackTrace();                }            }        }).start();        new Thread(new Runnable() {            public void run() {                // Sync sync =new Sync();                Thread current = Thread.currentThread();                System.out.println("currret thread id:" + current.getId() + "start...");                try {                    sync.thisSync();                } catch (InterruptedException e) {                    e.printStackTrace();                }            }        }).start();

结果:

currret thread id:9start...
current thread id:9enter...
1111
currret thread id:10start...
2222
3333
4444
5555
current thread id:9out...
current thread id:10enter...
1111
2222
3333
4444
5555
current thread id:10out...






0 0
原创粉丝点击