java 多线程同步
一.synchronized关键字
同步方法
每个对象都包含一把锁(也叫做监视器),它自动称为对象的一部分(不必为此写任何特殊的代码)。调用任何synchronized方法时,对象就会被锁定,不可再调用那个对象的其他任何synchronized方法,除非第一个方法完成了自己的工作。
示例代码如下:
public class SimpleThread implements Runnable {
	private int count = 0;
	@Override
	public void run() {
		while (true) {
			try {
				test();
			} catch (InterruptedException e) {
				e.printStackTrace();
			}
		}
	}
	private synchronized void test() throws InterruptedException {
		System.out.println(Thread.currentThread().getName() + ":" + count++);
		Thread.sleep(100);
	}
	public static void main(String[] args) {
		SimpleThread sd = new SimpleThread();
		for (int i = 0; i < 3; i++) {
			new Thread(sd).start();
		}
	}
}
同步块
在进入同步块之前,必须在synchObject上取得锁。如果已有其他线程取得了这把锁,块便不能进入,必须等候那把锁被释放。一般情况下,当前对象作为锁来使用。
示例代码如下:
public class SimpleThread implements Runnable {
	private int count = 0;
	@Override
	public void run() {
		while (true) {
			try {
				test();
			} catch (InterruptedException e) {
				e.printStackTrace();
			}
		}
	}
	private void test() throws InterruptedException {
		synchronized (this) {
			System.out.println(Thread.currentThread().getName() + ":" + count++);
		}
		Thread.sleep(100);
	}
	public static void main(String[] args) {
		SimpleThread sd = new SimpleThread();
		for (int i = 0; i < 3; i++) {
			new Thread(sd).start();
		}
	}
}
注:同步是一种高开销的操作,因此应该尽量减少同步的内容。 通常没有必要同步整个方法,使用synchronized代码块同步关键代码即可。
二.使用特殊域变量(volatile)
volatile关键字为域变量的访问提供了一种免锁机制,使用volatile修饰域相当于告诉虚拟机该域可能会被其他线程更新, 因此每次使用该域就要重新计算,而不是使用寄存器中的值,volatile不会提供任何原子操作,它也不能用来修饰final类型的变量。
public class SimpleThread implements Runnable {
	private volatile int count = 0;
	@Override
	public void run() {
		while (true) {
			try {
				test();
			} catch (InterruptedException e) {
				e.printStackTrace();
			}
		}
	}
	private void test() throws InterruptedException {
		System.out.println(Thread.currentThread().getName() + ":" + count++);
		Thread.sleep(100);
	}
	public static void main(String[] args) {
		SimpleThread sd = new SimpleThread();
		for (int i = 0; i < 3; i++) {
			new Thread(sd).start();
		}
	}
}
注:由于线程执行速度不一样,所以控制台打印的结果不全是按从大到小来的。
三.使用java.util.concurrent包
在JavaSE5.0中新增了一个java.util.concurrent包来支持同步。ReentrantLock类是可重入、互斥、实现了Lock接口的锁,它与使用synchronized方法和快具有相同的基本行为和语义,并且扩展了其能力。
示例代码如下:
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock; public class SimpleThread implements Runnable { private int count = 0; private Lock lock = new ReentrantLock(); @Override
public void run() {
while (true) {
try {
test();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
} private void test() throws InterruptedException {
lock.lock();
try {
System.out.println(Thread.currentThread().getName() + ":" + count++);
} finally {
lock.unlock();
} Thread.sleep(100);
} public static void main(String[] args) {
SimpleThread sd = new SimpleThread();
for (int i = 0; i < 3; i++) {
new Thread(sd).start();
}
} }
四.使用ThreadLocal管理变量
如果使用ThreadLocal管理变量,则每一个使用该变量的线程都获得该变量的副本,副本之间相互独立,这样每一个线程都可以随意修改自己的变量副本,而不会对其他线程产生影响。
示例代码如下:
public class SimpleThread implements Runnable {
	private ThreadLocal<Integer> count = new ThreadLocal<Integer>() {
		@Override
		protected Integer initialValue() {
			return 0;
		}
	};
	@Override
	public void run() {
		while (true) {
			try {
				test();
			} catch (InterruptedException e) {
				e.printStackTrace();
			}
		}
	}
	private void test() throws InterruptedException {
		System.out.println(Thread.currentThread().getName() + ":" + count.get().toString());
		count.set(count.get() + 1);
		Thread.sleep(100);
	}
	public static void main(String[] args) {
		SimpleThread sd = new SimpleThread();
		for (int i = 0; i < 3; i++) {
			new Thread(sd).start();
		}
	}
}
java 多线程同步的更多相关文章
- Java多线程同步问题的探究
		一.线程的先来后到——问题的提出:为什么要有多线程同步?Java多线程同步的机制是什么? http://www.blogjava.net/zhangwei217245/archive/2010/03/ ... 
- 转:关于JAVA多线程同步
		转:http://lanvis.blog.163.com/blog/static/26982162009798422547/ 因为需要,最近关注了一下JAVA多线程同步问题.JAVA多线程同步主要依赖 ... 
- java多线程同步
		一篇好文:java多线程机制同步原则 概括起来说,Java 多线程同步机制主要包含如下几点:1:如果一个类包含一个或几个同步方法,那么由此类生成的每一个对象都配备一个队列用来容纳那些等待执行同步的线程 ... 
- Java多线程-同步:synchronized 和线程通信:生产者消费者模式
		大家伙周末愉快,小乐又来给大家献上技术大餐.上次是说到了Java多线程的创建和状态|乐字节,接下来,我们再来接着说Java多线程-同步:synchronized 和线程通信:生产者消费者模式. 一.同 ... 
- Java多线程同步 synchronized 关键字的使用
		代表这个方法加锁,相当于不管哪一个线程A每次运行到这个方法时,都要检查有没有其它正在用这个方法的线程B(或者C D等),有的话要等正在使用这个方法的线程B(或者C D)运行完这个方法后再运行此线程A, ... 
- Java多线程---同步与锁
		一,线程的同步是为了防止多个线程访问一个数据对象时,对数据造成的破坏. 二.同步和锁定 1.锁的原理 Java中每个对象都有一个内置锁. 当程序运行到非静态的synchronized同步方法上时,自动 ... 
- Java多线程同步的方法
		一 synchronized关键字 1.synchronized实现原理: ---基于对象监视器(锁) java中所有对象都自动含有单一的锁,JVM负责跟踪对象被加锁的次数.如果一个对象被解锁,其计数 ... 
- Java 多线程同步的五种方法
		一.引言 闲话不多说,进入正题. 二.为什么要线程同步 因为当我们有多个线程要同时访问一个变量或对象时,如果这些线程中既有读又有写操作时,就会导致变量值或对象的状态出现混乱,从而导致程序异常.举个例子 ... 
- Java多线程同步问题:一个小Demo完全搞懂
		版权声明:本文出自汪磊的博客,转载请务必注明出处. Java线程系列文章只是自己知识的总结梳理,都是最基础的玩意,已经掌握熟练的可以绕过. 一.一个简单的Demo引发的血案 关于线程同步问题我们从一个 ... 
- java多线程同步(转)
		原文地址:http://developer.51cto.com/art/201509/490965.htm 一.场景 因为当我们有多个线程要同时访问一个变量或对象时,如果这些线程中既有读又有写操作时, ... 
随机推荐
- JVM垃圾回收机制总结(7) :调优方法
			JVM调优工具 Jconsole,jProfile,VisualVM Jconsole : jdk自带,功能简单,但是可以在系统有一定负荷的情况下使用.对垃圾回收算法有很详细的跟踪.详细说明参考这里 ... 
- 305.	Number of Islands II
			题目: A 2d grid map of m rows and n columns is initially filled with water. We may perform an addLand ... 
- Oracle下的IF EXISTS()
			妈蛋..作为一个使用了SQL SERVER有4 5年的程序猿,开始用Oracle真他妈不习惯.写法真他妈不一样.比如像写个像IF EXISTS(SELECT * FROM sys.tables WHE ... 
- SGU 125 Shtirlits  搜索+可行性剪枝
			500ms时限406ms水过…… 直接枚举肯定超时,需要剪枝. 枚举每个格子的元素,检查其左上角和正上方格子是否满足条件,若不满足不必再向下搜索. 在 这里 看到一个更好的方法: 枚举每个格子是哪个相 ... 
- Entity Framework学习 - 4.Code First升级数据库
			1.在nuget控制台中执行:Enable-Migrations 2.将出现的configuation.cs文件中的AutomaticMigrationsEnabled属性改为true 3.在nuge ... 
- 谈谈防止Ajax重复点击提交
			首先说说防止重复点击提交是什么意思. 我们在访问有的网站,输入表单完成以后,单击提交按钮进行提交以后,提交按钮就会变为灰色,用户不能再单击第二次,直到重新加载页面或者跳转.这样,可以一定程度上防止用户 ... 
- Mac 版 QQ 可直接访问 iPhone 的相册 ?!
			在QQ的聊天窗口中,点击 发送图片 的按钮,会有两个选择项,其中一个就是 从iPhone相册中选取 ,如图 点击 从iPhone相册中选取 后,iPhone上的QQ会收到一条消息 “请选择要上传的照 ... 
- boost静态链接的问题 -lgcc_s
			在使用gcc/g++ 编译程序时我们希望指向一些库是使用静态的链接方式. 另外的一些是动态的方式. 我以boost 为例. 如果我们要使用静态库则是这样的: # g++ main.cpp -lpthr ... 
- UVa 537 Artificial Intelligence?
			题目大意:输入一个字符串,根据物理公式P=U*I,已知其中两个量,求第三个量,结果保留两位小数. Artificial Intelligence? Physics teachers in hig ... 
- A1486. 树(王康宁)
			题目:http://www.tsinsen.com/A1486 题解: 其实看到和路径有关的就应该想到点分治. 我们找出重心之后遍历每一棵子树得到它的 { x=经过特殊点的个数,y=到rt的异或和} ... 
