多线程并发中的同步

多线程的同步依靠的是对象锁机制,synchronized关键字的背后就是利用了封锁来实现对共享资源的互斥访问。参考自http://www.cnblogs.com/phinecos/archive/2010/03/13/1684877.html

 

实例说明:1.貌似同步,实际不同步的情况

package com.thread.code.sync;

/**
 * 不能实现线程同步的例子
 * @author  魅力_小生
 * @version  [版本号, 2016年3月4日]
 */
public class CannotSync
{
    public static void main(String[] args)
    {
        CannotSync test = new CannotSync();
        //定义5个线程,希望不打断输出:线程1--1..5;线程2--1..5;...线程5--1..5;
        for (int i = 0; i < 5; i++)
        {
            new Thread(test.new MyThread(),"线程"+i).start();
        }
        //结果发现:打印结果并没有按顺序输出
        /*
         * 原因:在普通方法前面加synchronized,锁住的是当前的this对象,也就是每个个new MyThread()对象;
         *      代码中创建了10个线程,而每个线程都持有this对象的对象锁,这不能实现线程的同步
         */
    }
    
    class MyThread implements Runnable{
        @Override
        //貌似同步,实际不同步(当只有一个线程调用时同步,多线程时不同步)
        public synchronized void run()
        {
            for (int i = 0; i < 10; i++)
            {
                System.out.println(Thread.currentThread().getName()+"--"+i);
            }
        }
    }
}

打印结果:线程1未执行完,线程3打断,接着线程4又打断3,接着线程2又打断4...

线程1--0
线程1--1
线程1--2
线程1--3
线程1--4
线程1--5
线程3--0
线程4--0
线程2--0
线程2--1
线程2--2
线程2--3
线程2--4
线程2--5
线程0--0
...

 

下面看看能实现同步的几种情况:

1.同步锁指向同一个对象(外部定义的对象)

package com.thread.code.sync;

/**
 * 实现线程同步的例子1:同步锁指向同一个对象(外部定义的对象)
 * @author  魅力_小生
 * @version  [版本号, 2016年3月4日]
 */
public class Sync1
{
    public static void main(String[] args)
    {
        Sync1 test = new Sync1();
        
        //定义一个共用obj,用于共享资源的锁指向同一个对象,实现同步
        Object obj = new Object();
        //定义5个线程,共同竞争同步代码块,先竞争到的先执行完同步块,中间不会被打断
        for (int i = 0; i < 5; i++)
        {
            new Thread(test.new MyThread(obj),"线程"+i).start();
        }
    }
    
    class MyThread implements Runnable{
        private Object obj;
        public MyThread(Object obj){
            this.obj = obj;
        }
        @Override
        public void run()
        {
            synchronized(obj){
                for (int i = 0; i < 10; i++)
                {
                    System.out.println(Thread.currentThread().getName()+"--"+i);
                }
                System.out.println("------------");
            }
        }
    }
}

2.同步锁指向同一个对象(内部定义静态对象)

package com.thread.code.sync;

/**
 * 实现线程同步的例子2:同步锁指向同一个对象(内部定义静态对象)
 * @author  魅力_小生
 * @version  [版本号, 2016年3月4日]
 */
public class Sync2
{
    public static void main(String[] args)
    {
        //定义5个线程,共同竞争同步代码块,先竞争到的先执行完同步块,中间不会被打断
        for (int i = 0; i < 5; i++)
        {
            new Thread(new MyThread(),"线程"+i).start();
        }
    }
    
    static class MyThread implements Runnable{
        //定义静态对象,用于共享资源的锁指向同一个对象,实现同步
        private static Object obj = new Object();
        @Override
        public void run()
        {
            synchronized(obj){
                for (int i = 0; i < 10; i++)
                {
                    System.out.println(Thread.currentThread().getName()+"--"+i);
                }
                System.out.println("------------");
            }
        }
    }
}

3.使用静态同步方法,而不是普通同步方法

package com.thread.code.sync;

/**
 * 实现线程同步的例子3:使用静态同步方法,而不是普通同步方法
 * @author  魅力_小生
 * @version  [版本号, 2016年3月4日]
 */
public class Sync3
{
    public static void main(String[] args)
    {
        //定义5个线程,希望不打断输出:线程1--1..5;线程2--1..5;...线程5--1..5;
        for (int i = 0; i < 5; i++)
        {
            new Thread(new MyThread(),"线程"+i).start();
        }
    }
    
    static class MyThread implements Runnable{
        @Override
        public void run()
        {
            print();
        }
        /*
         * 静态同步方法:
         *  静态方法是所有类实例对象所共享的,因此线程对象在访问此静态方法时是互斥访问的,从而可以实现线程的同步
         */
        private static synchronized void print()
        {
            for (int i = 0; i < 10; i++)
            {
                System.out.println(Thread.currentThread().getName()+"--"+i);
            }
            System.out.println("------------");
        }
    }
}

 

上面这些同步情况的打印结果:线程竞争到资源后,未被打断

线程0--0
线程0--1
线程0--2
线程0--3
线程0--4
线程0--5
线程0--6
线程0--7
线程0--8
线程0--9
------------
线程3--0
线程3--1
线程3--2
线程3--3
线程3--4
线程3--5
线程3--6
线程3--7
线程3--8
线程3--9
------------
线程4--0
线程4--1
线程4--2
线程4--3
线程4--4
线程4--5
线程4--6
线程4--7
线程4--8
线程4--9
------------
线程2--0
线程2--1
线程2--2
线程2--3
线程2--4
线程2--5
线程2--6
线程2--7
线程2--8
线程2--9
------------
线程1--0
线程1--1
线程1--2
线程1--3
线程1--4
线程1--5
线程1--6
线程1--7
线程1--8
线程1--9
------------

 

posted @ 2016-03-04 15:39  艺言弈行  阅读(657)  评论(0编辑  收藏  举报