首页

关于线程同步使用synchronized和Lock对比及代码示例

标签:java,java基础,Lock,ReentrantLock,synchronized,用法,线程安全,并发控制,锁,demo     发布时间:2015-06-18   

一、对比说明

Synchronized:JVM级别的锁,是JVM的内置属性,可以重入,对于前言中的例子,我们可以加入Synchronized解决问题,如下所示

ReentrantLock:  JAVA类库级别的,功能更多:支持等待可中断,公平锁等等

需要获取更多相关知识,跳转到“Java并发编程基础知识分享

二、代码示例

1. synchronized用法

synchronized可以用户代码块、方法、静态方法、类加锁控制,具体用法如下所示

synchronized方法,针对同一对象,否则无法控制,示例代码如下:

package jh.modules.current;@b@@b@public class TestObjSynchronized {@b@    private  long pc=0;@b@    public   synchronized void print(){@b@        while(pc<10){@b@            pc++;@b@            if(pc%2==0)@b@                System.out.println(Thread.currentThread().getName()+"@pc:"+pc);@b@        }@b@    }@b@    /**@b@     * @param args@b@     */@b@    public static void main(String[] args) {@b@        // TODO Auto-generated method stub@b@        @b@        Runnable h1=new Runnable(){@b@            @Override@b@            public void run() {@b@                // TODO Auto-generated method stub@b@                TestObjSynchronized o=new TestObjSynchronized();@b@                o.print();@b@            }@b@            @b@        };@b@        @b@        Thread t1=new Thread(h1);@b@        Thread t2=new Thread(h1);@b@        t1.start();@b@        t2.start();@b@    }@b@}

运行结果,不能控制线程独占:

Thread-1@pc:2@b@Thread-0@pc:2@b@Thread-1@pc:4@b@Thread-0@pc:4@b@Thread-0@pc:6@b@Thread-1@pc:6@b@Thread-0@pc:8@b@Thread-1@pc:8@b@Thread-0@pc:10@b@Thread-1@pc:10

synchronized类可以实现,示例如下

public class TestObjSynchronized {@b@        private  long pc=0;@b@        public   void print(){@b@            synchronized(TestObjSynchronized.class){@b@                while(pc<10){@b@                    pc++;@b@                    if(pc%2==0)@b@                        System.out.println(Thread.currentThread().getName()+"@pc:"+pc);@b@                }@b@            }@b@        }@b@        public static void main(String[] args) {@b@            Runnable h1=new Runnable(){@b@                @Override@b@                public void run() {@b@                    TestObjSynchronized o=new TestObjSynchronized();@b@                    o.print();@b@                }@b@                @b@            };@b@            Thread t1=new Thread(h1);@b@            Thread t2=new Thread(h1);@b@            t1.start();@b@            t2.start();@b@        }@b@}

运行结果,可以实现线程控制

Thread-0@pc:2@b@Thread-0@pc:4@b@Thread-0@pc:6@b@Thread-0@pc:8@b@Thread-0@pc:10@b@Thread-1@pc:2@b@Thread-1@pc:4@b@Thread-1@pc:6@b@Thread-1@pc:8@b@Thread-1@pc:10

synchronized静态方法也可以,示例代码如下:

package jh.modules.current;@b@@b@public class TestSynchronized {@b@    private static long pc=0;@b@    public static synchronized void print(){@b@        while(pc<10){@b@            pc++;@b@            if(pc%2==0)@b@                System.out.println(Thread.currentThread().getName()+"@pc:"+pc);@b@        }@b@    }@b@    /**@b@     * @param args@b@     */@b@    public static void main(String[] args) {@b@        // TODO Auto-generated method stub@b@        @b@        Runnable h1=new Runnable(){@b@            @Override@b@            public void run() {@b@                // TODO Auto-generated method stub@b@                TestSynchronized.print();@b@            }@b@            @b@        };@b@        Thread t1=new Thread(h1);@b@        Thread t2=new Thread(h1);@b@        t1.start();@b@        t2.start();@b@    }@b@@b@}

运行结果如下:

Thread-0@pc:2@b@Thread-0@pc:4@b@Thread-0@pc:6@b@Thread-0@pc:8@b@Thread-0@pc:10

synchronized对象this和类组合对比,线程按顺序执行

package thread.lock;@b@@b@public class TestSynchronized {@b@	@b@	public void test1() {@b@		synchronized (this) {@b@			int i = 5;@b@			while (i-- > 0) {@b@				System.out@b@						.println(Thread.currentThread().getName() + " : " + i);@b@				try {@b@					Thread.sleep(500);@b@				} catch (InterruptedException ie) {@b@				}@b@			}@b@		}@b@	}@b@@b@	public synchronized void test2() {@b@		int i = 5;@b@		while (i-- > 0) {@b@			System.out.println(Thread.currentThread().getName() + " : " + i);@b@			try {@b@				Thread.sleep(500);@b@			} catch (InterruptedException ie) {@b@			}@b@		}@b@	}@b@@b@	public static void main(String[] args) {@b@		final TestSynchronized myt2 = new TestSynchronized();@b@		Thread test1 = new Thread(new Runnable() {@b@			public void run() {@b@				myt2.test1();@b@			}@b@		}, "test1");@b@		Thread test2 = new Thread(new Runnable() {@b@			public void run() {@b@				myt2.test2();@b@			}@b@		}, "test2");@b@		test1.start();  @b@		test2.start(); @b@		@b@	}@b@@b@}

控制台运行结果

test1 : 4@b@test1 : 3@b@test1 : 2@b@test1 : 1@b@test1 : 0@b@test2 : 4@b@test2 : 3@b@test2 : 2@b@test2 : 1@b@test2 : 0

2. Lock用法

使用Lock实现多对象都线程独占控制,示例如下:

package jh.modules.current;@b@@b@import java.util.concurrent.locks.Lock;@b@import java.util.concurrent.locks.ReentrantLock;@b@@b@public class TestLock {@b@    private static Lock lock=new ReentrantLock();@b@    private    long pc=0;@b@    public     void print(){@b@        lock.lock();@b@        while(pc<10){@b@            pc++;@b@            if(pc%2==0)@b@                System.out.println(Thread.currentThread().getName()+"@pc:"+pc);@b@        }@b@        lock.unlock();@b@    }@b@@b@    /**@b@     * @param args@b@     */@b@    public static void main(String[] args) {@b@        // TODO Auto-generated method stub@b@        Runnable h1=new Runnable(){@b@            @Override@b@            public void run() {@b@                // TODO Auto-generated method stub@b@                TestLock t=new TestLock();@b@                t.print();@b@            }@b@            @b@        };@b@        Thread t1=new Thread(h1);@b@        Thread t2=new Thread(h1);@b@        t1.start();@b@        t2.start();@b@    }@b@@b@}

运行结果如下:

Thread-0@pc:2@b@Thread-0@pc:4@b@Thread-0@pc:6@b@Thread-0@pc:8@b@Thread-0@pc:10@b@Thread-1@pc:2@b@Thread-1@pc:4@b@Thread-1@pc:6@b@Thread-1@pc:8@b@Thread-1@pc:10

 Lock一般会结合Condition使用,示例如下:

package thread.lock;@b@@b@import java.util.concurrent.locks.Condition;@b@import java.util.concurrent.locks.Lock;@b@import java.util.concurrent.locks.ReentrantLock;@b@ @b@/**@b@ *  类描述@b@ * @author nijun@b@ * @version v1.0 版本创建于  2015-6-19@b@ * @version v1.1更新于2021-09-04@b@ */@b@ @b@public class TestLock_Condition {@b@     @b@    static class NumberWrapper {@b@        public int value = 1;@b@    }@b@ @b@    public static void main(String[] args) {@b@         @b@        //初始化同步锁@b@        final Lock lock = new ReentrantLock();@b@         @b@        //条件输出1到3@b@        final Condition reach1_3Condition = lock.newCondition();@b@        //条件输出4到6@b@        final Condition reach4_6Condition = lock.newCondition();@b@         @b@        //NumberWrapper封装Integer不可变类,@b@        final NumberWrapper num = new NumberWrapper();@b@         @b@        //线程0(A) 用于输出1-3、7-9@b@        Thread threadA = new Thread(new Runnable() {@b@            @Override@b@            public void run() {@b@                //需要先获得锁@b@                lock.lock();@b@                try {@b@                    //1线程先输出前3个数@b@                    while (num.value <= 3) {@b@                        System.out.println(Thread.currentThread().getName()+":"+num.value);@b@                        num.value++;@b@                    }@b@                    //输出到3时要signal,通知线程2运行@b@                    reach1_3Condition.signal();@b@                } finally {@b@                    lock.unlock();@b@                }@b@                lock.lock();@b@                try {@b@                    //等待线程2返回@b@                    reach4_6Condition.await();@b@                    //输出剩余数字@b@                    while (num.value <= 9) {@b@                        System.out.println(Thread.currentThread().getName()+":"+num.value);@b@                        num.value++;@b@                    }@b@ @b@                } catch (InterruptedException e) {@b@                    e.printStackTrace();@b@                } finally {@b@                    lock.unlock();@b@                }@b@            }@b@ @b@        });@b@ @b@      //线程1(B) 用于输出4-6@b@        Thread threadB = new Thread(new Runnable() {@b@            @Override@b@            public void run() {@b@                try {@b@                    lock.lock();@b@                    while (num.value <= 3) {@b@                        //等待3输出完毕的信号@b@                        reach1_3Condition.await();@b@                    }@b@                } catch (InterruptedException e) {@b@                    e.printStackTrace();@b@                } finally {@b@                    lock.unlock();@b@                }@b@                try {@b@                    lock.lock();@b@                    //准备输出4,5,6@b@                    while (num.value <= 6) {@b@                        System.out.println(Thread.currentThread().getName()+"->"+num.value);@b@                        num.value++;@b@                    }@b@                    //4,5,6输出完毕,告诉A线程6输出完了@b@                    reach4_6Condition.signal();@b@                } finally {@b@                    lock.unlock();@b@                }@b@            }@b@ @b@        });@b@ @b@ @b@        //启动两个线程@b@        threadB.start();@b@         @b@        threadA.start();@b@         @b@    }@b@ @b@}

控制台结果

Thread-0:1@b@Thread-0:2@b@Thread-0:3@b@Thread-1->4@b@Thread-1->5@b@Thread-1->6@b@Thread-0:7@b@Thread-0:8@b@Thread-0:9
<<推荐下载>>
  • (1) 阿里巴巴Java开发手册8种不同版本
  • (2) Web前端开发视频教程
  • (3) 30+明星讲师PPT课件分享一线大厂架构实战经验
  • (4) java开发_架构篇_视频资源分享_v2208
  • (5) java开发_高级篇_视频资源分享_v2208
  • (6) java开发_进阶篇(中级)_视频资源分享_v2208
  • (7) java开发_入门篇_视频资源分享_v2208
  • (8) 微信小程序开发视频1+167源码+实战demo等下载
  • (9) easy-shopping电子商务java源码(附脚本和安装文档说明)下载
  • (10) java常用的72份知名实用的电子书下载
  • (11) java开发性能优化资料整理大全(8份电子文档+3份实战优化)下载
  • (12) 9个常用的算法设计资料和100以上视频课件内容下载
  • (13) vue开发必备常用手册16件下载
  • (14) 21种不同技术集群方案(es、flink、redis、nginx、zk、lvs、kafka、mysql、k8s等)参考资料下载
  • (15) 20种技术代码规范(js/java/dba/阿里/华为/oracle/mysql等)参考资料下载
  • (16) 微服务五套资料(0-1,架构设计,springcloud,nacos等)下载
  • (17) 架构师(28知识图谱+3套简历模板+6套架构实战文档等)完整资料整理下载
  • (18) 大数据18套实战基础知识+8套简历模板下载
  • (19) 并发编程全套(7套+阿里巴巴+亿级实战等)实战资料下载
  • (20) Kafka九套学习整理知识点全套(面试+笔记+代码api+命令+容备等)资料下载
  • (21) java全套9个不同方向类型的面试题(基础+核心+大厂+架构师+近万套题库等)下载
  • (22) JAVA开发常用API帮助文档大全(超52种以上技术资料,高手必备)下载
  • (23) springcloud超详细139件全套学习实战资料( 视频课件+源码demo+文档资料等)下载
  • 更多推荐>>
  • <<热门文章>>