博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
java线程 在其他对象上同步、线程本地存储ThreadLocal:thinking in java4 21.3.6
阅读量:5805 次
发布时间:2019-06-18

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

hot3.png

 java线程 在其他对象上同步、线程本地存储ThreadLocal:thinking in java4 21.3.6

package org.rui.thread.concurrency;/** * 在其他对象上同步 * synchronized 块必须给定一个在其上进行同步的对象,并且最合理的方式是,使用其方法正在被调用的当前对象 * :synchronized(this), 在 这种方式中,如果获得了synchronized块上的锁, * 那么该对象其他的synchronized方法和临界区就不能被调用了。 * 因此,如果在this上同步,临界区的效果就会直接缩小在同步的范围内. *  * 有时必须在另一个对象上同步,但是如果你要这么做,就必须确保所有相关任务都是在同一个对象上同步的。 * 下面的示例演示了两个任务可以同时进入同一个对象, * 只要这个对象上的方法是在不同中的锁上同步的即可 * @author lenovo * */class DualSynch{  private Object syncObject=new Object();  public synchronized void f()  {	  for(int i=0;i<5;i++)	  {		  System.out.println("f()");		  Thread.yield();	  }  }public void g(){  synchronized (syncObject)   {	for(int i=0;i<5;i++)	{		System.out.println("g()");		Thread.yield();	}   }	}}public class SyncObject {	public static void main(String[] args)	{		final DualSynch ds =new DualSynch();		//另一个 线程		new Thread()		{			public void run() 			{				ds.f();			};		}.start();				//g()		ds.g();	}}/** * DualSyn.f()通过同步整个方法   在this上同步,面g()有一个在syncObject上同步的synchronized块 * 因此,这两个同步是互相独立的。通过在main()中创建调用f()的thread对这一点进行了演示, * 因此,这两个同步是互相独立的.从输出中可以看到, * 这两个方法在同时运行,因此任何一个方法都没有因为对另一个方法的同步而被阻塞 *  *  * output(sample)g()f()g()f()f()f()f()g()g()g() */
package org.rui.thread.concurrency;import java.util.Random;import java.util.concurrent.ExecutorService;import java.util.concurrent.Executors;import java.util.concurrent.TimeUnit;/** * 线程本地存存储 *  * 防步任务共享资源上产生冲突的第二种方式是根除对变量共享。 * 线程本地存储是一种自动化机制,可以为使用相同变量的每个不同的线程都创建不同的存储。因此, * 如果你有5个线程都要使用变量X所表示的对象,那线程本地存储就会生成5个用于x的不同的存储块。主要是, * 它们使得你可以将状态与线程关联起来。 * @author lenovo * */class Accessor implements Runnable{	private final int id;	public  Accessor(int idn){id=idn;}	@Override	public void run() {		while(!Thread.currentThread().isInterrupted())		{			ThreadLocalVariableHolder.incrment();			System.out.println(this);			Thread.yield();		}			}		//toString()	@Override	public String toString() {		return "#"+id+": "+ThreadLocalVariableHolder.get();	}	}///public class ThreadLocalVariableHolder {	private static ThreadLocal
value= new ThreadLocal
() { private Random rand=new Random(47); protected synchronized Integer initialValue() { return rand.nextInt(10000); } }; public static void incrment() { value.set(value.get()+1); } public static int get(){return value.get();} public static void main(String[] args) throws Exception { ExecutorService exec=Executors.newCachedThreadPool(); for(int i=0;i<5;i++) exec.execute(new Accessor(i)); TimeUnit.SECONDS.sleep(3);//run for a while exec.shutdownNow();// all accessors will quit }}/** * ThreadLocal对象通常当作静态域存储。在创建ThreadLocal时,你只能通过get() set()方法来访问该对象的内容, * 其中,get()方法将返回与其线程相关联的对象副本,而set会将参数插入到为其线程存储的对象中,并返回存储中原有的对象。 * increment()和get()方法在这里演示了这点, ThreadLocal保证不会出现竞争条件. * * * * output(sample) #1: 39807#1: 39808#1: 39809#1: 39810#1: 39811#1: 39812#0: 44495#4: 41633#4: 41634#4: 41635#4: 41636#4: 41637#4: 41638#4: 41639#4: 41640 */

转载于:https://my.oschina.net/pangzhuzhu/blog/301783

你可能感兴趣的文章
1083 Cantor表
查看>>
字符集对应表
查看>>
apicloud,aliyunlive,测试成功
查看>>
判断一个数是否含有相同的数字
查看>>
Logstash读写性能调整优化
查看>>
Android实践 -- 设置系统日期时间和时区
查看>>
解决input框中加入disabled="disabled"之后,改变字体的颜色(默认的是灰色)
查看>>
XML数据库的尝试
查看>>
解决:MVC对象转json包含\r \n
查看>>
【Java】Java_14 循环结构
查看>>
UVa 10179 - Irreducable Basic Fractions
查看>>
Spark-Dependency
查看>>
R语言绘图布局
查看>>
Java内存区域与模拟内存区域异常
查看>>
Eclipse集成weblogic教程
查看>>
Android 依赖注入: Dagger 2 实例解说(一)
查看>>
crazyflie2.0 RCC时钟知识
查看>>
C. Glass Carving (CF Round #296 (Div. 2) STL--set的运用 &amp;&amp; 并查集方法)
查看>>
leetcode第一刷_Symmetric Tree
查看>>
嵌套的异步回调
查看>>