博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
Thread - synchronized
阅读量:4202 次
发布时间:2019-05-26

本文共 3304 字,大约阅读时间需要 11 分钟。

同步的关键是多个线程对象竞争同一个共享对象,使无序的多个线程有序地排队。

Example 1:

public class Thread06_sync {	public static void main(String[] args) {//		new Thread06_sync().test01();		new Thread06_sync().new Test02(new Object()).test02();	}	// 同步失败,原因:不是同步同一个对象	public void test01() {		for (int i = 1; i <= 3; ++i) {			new Thread(new Runnable() {				public synchronized void run() {					for (int i = 1; i <= 5; ++i) {						System.out.println("id:"								+ Thread.currentThread().getId() + ",i:" + i);					}				}			}).start();		}	}	// 同步成功,原因:同步同一个对象	public class Test02 {		private Object thisThread;		public Test02(Object thisThread) {			this.thisThread = thisThread;		}		public void test02() {			for (int i = 1; i <= 3; ++i) {				new Thread(new Runnable() {					public void run() {						synchronized (thisThread) {							for (int i = 1; i <= 5; ++i) {								System.out.println("id:"										+ Thread.currentThread().getId() + ",i:" + i);							}						}					}				}).start();			}		}	}}

第一个例子,如果不同的synchronized object, 则不能正确lock住代码片段。

Example 2:

public class Thread04_static {	// volatile 只是可见一致性,非原子性(也就是无写锁),仍然有机会有重复uniqueNumber的输出	public volatile static long uniqueNumber = 0;		static int threadNumber = 5;	static AtomicInteger testNum = new AtomicInteger(0);	static List
resultList = new ArrayList<>(300); private final static ReentrantLock lock = new ReentrantLock(); public static void main(String[] args) { testThread01(); } // CountDownLatch public static void testThread01() { try { CountDownLatch doneSignal = new CountDownLatch(50); for (int i = 0; i < threadNumber; i++) { Thread thread = new Thread(new Thread04_static().new TestThread01(doneSignal)); thread.setName("t_" + i); thread.start(); } // 由于thread的无序性,不加await的话, 有可能运行下面语句时thread还没运行,resultList有可能是空值 doneSignal.await(); int i = 1; for (Long result : resultList) { System.out.println("result_" + i + ":" + result); ++i; } } catch (Exception e) { e.printStackTrace(); } } // 静态类及非静态同步、锁测试 public class TestThread01 implements Runnable { private CountDownLatch doneSignal; public TestThread01(CountDownLatch doneSignal) { this.doneSignal = doneSignal; } public void run() { try { // 第一个同步block/ReentrantLock:这里的同步无预期效果(即有重复的uniqueNumber出现),因为getUniqueNum是类静态方法// synchronized (this) {// lock.lock(); for (int i = 0; i < 10; i++) {// System.out.println(testNum.addAndGet(1)); // 有重复的testNum出现, 原因:testNum是原子的,但下面的语句不原子// System.out.println("Thread:" + Thread.currentThread().getName() + ", testNum:" + testNum + ", i:" + i); resultList.add(getUniqueNum(2)); doneSignal.countDown(); } // 空行不一定每十条记录输出一次,因为它不在下面的静态同步block System.out.println(""); Thread.sleep(1000);// } } catch (Exception e) { e.printStackTrace(); } finally {// lock.unlock(); } } } public static Long getUniqueNum(int len) { // 第二个同步block/ReentrantLock:静态类同步block/lock,实现无重复uniqueNumber输出// synchronized (TestThread01.class) { try{ lock.lock(); if (len < 1) { return null; } if (uniqueNumber < (Math.pow(10, len) - 1)) { uniqueNumber++; } System.out.println("Thread:" + Thread.currentThread().getName() + ", uniqueNumber:" + uniqueNumber); return uniqueNumber; } finally { lock.unlock(); }// } }}
第二个例子,static 和 非static的不同,也会导致lock的失败。

转载地址:http://pwili.baihongyu.com/

你可能感兴趣的文章
数据库备份与还原: 1.mysqldump备份 source还原 2.heidisql64.r5138 备份mysql数据
查看>>
mysql为已经定义好的表添加主键: ALTER TABLE t_user ADD PRIMARY KEY (`uid`);
查看>>
node.js异步问题终极解决: 1.async+await解决回调地狱 2.async+await+Promise.all+try catch用于并发执行,并处理异常
查看>>
面向对象之cc.class子类调用父类的方法(IFTTTSoundAnim.prototype.do_right_action(data, then))
查看>>
c++编译器调用C函数,必须加 extern "C" {}(不要变名字) 不然报错(原因: c++有函数重载机制导致的命名改变导致函数找不到)
查看>>
用SpringCloud Alibaba搭建属于自己的微服务(一)~产品需求
查看>>
用SpringCloud Alibaba搭建属于自己的微服务(二)~技术选型
查看>>
用SpringCloud Alibaba搭建属于自己的微服务(三)~准备工作~mysql,elasticsearch,kafka,redis的安装
查看>>
用SpringCloud Alibaba搭建属于自己的微服务(四)~基础搭建~maven工程管理
查看>>
用SpringCloud Alibaba搭建属于自己的微服务(六)~基础搭建~启动第一个springboot工程server-user
查看>>
用SpringCloud Alibaba搭建属于自己的微服务(五)~基础搭建~cloud、cloud alibaba和boot的版本选择
查看>>
用SpringCloud Alibaba搭建属于自己的微服务(七)~基础搭建~springboot整合druid和mybatisPlus
查看>>
用SpringCloud Alibaba搭建属于自己的微服务(八)~基础搭建~springboot整合swagger接口文档
查看>>
用SpringCloud Alibaba搭建属于自己的微服务(九)~基础搭建~参数校验框架的使用
查看>>
用SpringCloud Alibaba搭建属于自己的微服务(十)~基础搭建~自定义异常、统一结果集和全局异常处理器
查看>>
用SpringCloud Alibaba搭建属于自己的微服务(十一)~基础搭建~alibaba nacos的安装
查看>>
用SpringCloud Alibaba搭建属于自己的微服务(十二)~基础搭建~alibaba nacos的服务注册和发现
查看>>
用SpringCloud Alibaba搭建属于自己的微服务(十五)~基础搭建~使用openfeign集成ribbon负载均衡.
查看>>
用SpringCloud Alibaba搭建属于自己的微服务(十六)~基础搭建~openfegin+ribbon的rpc调用高可用之重试机制
查看>>
用SpringCloud Alibaba搭建属于自己的微服务(十七)~基础搭建~alibaba sentinel服务端的安装
查看>>