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<Integer> value=
			new ThreadLocal<Integer>()
			{
		      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
 */

java线程 在其他对象上同步、线程本地存储ThreadLocal:thinking in java4 21.3.6,布布扣,bubuko.com

时间: 2024-10-26 03:29:44

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

线程与内核对象的同步

线程与内核对象的同步内核对象可以处于已通知或未通知状体进程,线程,作业,文件,控制台输入,文件修改,事件,可等待定时器 等待函数DWORD WaitForSingleObject(HANDLE hobject, DWORD dwMilliseconds); 同时查看若干个内核对象已通知状体DWORD WaitForMultipleObjects(DWORD dwCount,CONST HANDLE* phObjects,BOOL fWaitAll,DWORD dwMilliseconds);dw

从头认识java-18.6 synchronized在其他对象上同步和ThreadLocal来消除共享对象的同步问题

这一章节我们来介绍在其他对象上同步与ThreadLocal. 前一章节我们使用了 1.synchronized在其他对象上同步 class ThreadA implements Runnable { private Object object = new Object(); private synchronized void test() throws InterruptedException { System.out.println("dosomething"); Thread.sl

在其他对象上同步

synchronized 块必须给定一个在其上进行同步的对象,并且最合理的方式是,使用其方法正在被调用的当前对象:synchronized(this). 在此种方式中,如果获得了synchronized块上同步锁,那么该对象其他的synchronized方法和临界区就不能被调用.因此,如果再this上同步, 临界区的效果就会直接缩小在同步的范围内. 但有时必须在另一个对象上同步,如果这么做,就必须确保所有相关的任务都是在对象上同步的.例如下面例子俩个任务可以同时进入同一个 对象,只要此对象上的方

Windows API学习---线程与内核对象的同步

前言 若干种内核对象,包括进程,线程和作业.可以将所有这些内核对象用于同步目的.对于线程同步来说,这些内核对象中的每种对象都可以说是处于已通知或未通知的状态之中.这种状态的切换是由Microsoft为每个对象建立的一套规则来决定的.例如,进程内核对象总是在未通知状态中创建的.当进程终止运行时,操作系统自动使该进程的内核对象处于已通知状态.一旦进程内核对象得到通知,它将永远保持这种状态,它的状态永远不会改为未通知状态. 当进程正在运行的时候,进程内核对象处于未通知状态,当进程终止运行的时候,它就变

Linux平台用C++实现事件对象,同步线程(转)

本文属于转载,原文链接如下:http://blog.csdn.net/chexlong/article/details/7080537 与其相关的一组API包括:pthread_mutex_init,pthread_cond_init,pthread_mutex_lock,pthread_cond_wait,pthread_mutex_unlock,pthread_cond_broadcast,pthread_cond_timedwait,pthread_cond_destroy,pthread

线程与内核对象的同步-2

等待定时器内核事件CreateWaitableTimer(PSECURITY_ATTRIBUTES psa,BOOL fManualReset,PCTSTR pszName);进程可以获得它自己的与进程相关的现有等待定时器的句柄.HANDLE OpenWaitableTimer(DWORD dwDesiredAccess,BOOL bInheritHandle,PCTSTR pszName); 等待定时器对象总是在未通知状态中创建,必须调用SetWaitableTimer函数来告诉定时器你想在何

38.线程三--&gt;多线程数据安全和同步线程的方法

学习要点 多线程数据安全 同步线程的方法 class MyThread implements Runnable{//MyThread 实现Runnable接口 int i = 100; public void run(){ //复写run方法 while(true){ synchronized(this){  //线程同步代码 //Thread.currentThread()获取当前这段代码正在哪个线程运行 System.out.println(Thread.currentThread().ge

Java ConcurrentHashMap存入引用对象时也是线程安全的

本人小白,看到资料说ConcurrentHashMap是线程安全的,get过程不需要加锁,put是线程安全的,推荐高并发时使用.但是本人不清楚是否该map中存入的引用类型对象,对象属性变化也是否线程安全的,看了很多资料,貌似都没说明这一点,所以写代码测试一下, package testConcurrentHashMap; import java.util.concurrent.ConcurrentHashMap; /** * Created by xuzimian on 17-3-1. */ p

为什么有可能会被多个线程修改的对象要加线程锁

例1.不用线程锁的情况下,两个线程对同一个变量进行加减操作 static void Main(string[] args) { Counter counter = new Counter(); var t1 = new Thread(() => TestCounter(counter)); var t2 = new Thread(() => TestCounter(counter)); t1.Start(); t2.Start(); Thread.Sleep(TimeSpan.FromSeco