`
thrillerzw
  • 浏览: 139005 次
  • 性别: Icon_minigender_1
  • 来自: 北京
社区版块
存档分类
最新评论

多线程

    博客分类:
  • java
 
阅读更多

一 同步

同步方法,同步块。

synchronized methodA(), synchronized static  methodA()

synchronized(this){  } ,   synchronized (XXX.class){  }

 

当一个线程进入一个对象的一个synchronized方法后,其它线程是否可进入此对象的其它方法?
一个线程进入一个对象的synchronized方法后,即获得了这个对象的锁,也就是占有了这个对象。这个对象的其他synchroized方法和方法块,是不能被其他线程所访问的。但这个对象的非synchroized方法,是可以被其它线程所访问的。这个方法同步代码块前有代码,还是可以访问的。

 

synchronized (XXX.class)和synchronized(this)前者锁的是该类的类对象的对象锁,后者锁的是当前对象。

 

package common;

public class SyTest {
	private String a = "abc";

	private String b = "def";

	private void test1() throws InterruptedException {
		// synchronized (this) {
		synchronized (a.getClass()) { //synchronized (String.class) {
			System.out.println("A");
			Thread.sleep(5000);
		}
	}

	private void test2() throws InterruptedException {
		System.out.println("before synchronized B");
//		synchronized (this) {
		synchronized (b.getClass()) {  //synchronized (String.class) {
			System.out.println("B");
			Thread.sleep(5000);
		}
	}

	public static void main(String args[]) {
		//final SyTest syTest = new SyTest();
		new Thread() {
			public void run() {
				try {
//					syTest.test1();
					new SyTest().test1(); 
				} catch (InterruptedException ex) {
					ex.printStackTrace();
				}
			}
		}.start();
		
		try {
			Thread.sleep(100);
		} catch (InterruptedException e) {
			e.printStackTrace();
		}
		new Thread() {
			public void run() {
				try {
//					syTest.test2();
					new SyTest().test2(); 
				} catch (InterruptedException ex) {
					ex.printStackTrace();
				}
			}
		}.start();
	}
}

 

打印出: 先打印前2行,过了5秒打印出B

A
before synchronized B

 

在没有对象的时候,使用类锁(该类的类对象的对象锁),如单例:

public class Singleton{       
        private Singleton(){}
	private volatile static Singleton instance = null;
	public static Singleton getInstance() {
		if (instance == null) {
			synchronized (Singleton.class) {
				if (instance == null) {
					instance = new Singleton();
				}
			}
		}
		
		return instance;
	}
}

 

二 线程池

 1、ThreadPoolExecutor原理:  http://thrillerzw.iteye.com/blog/1852760

 

多线程测试代码:

 

	int numOfThreads =Runtime.getRuntime().availableProcessors()*2;
	        ExecutorService executor = Executors.newFixedThreadPool(numOfThreads); 
			List<Future<Long>> results = new ArrayList<Future<Long>>();   
	        for (int i = 0; i < 500; i++) {
	        	/*
	        	 * 
				<T> Future<T>	submit(Callable<T> task) 
	        	 * Callable 接口类似于 Runnable,两者都是为那些其实例可能被另一个线程执行的类设计的。
	        	但是 Runnable 不会返回结果,并且无法抛出经过检查的异常。
	        	call return  Long  (new Callable<Long> 中的)
	        	*/
	        	//添加的过程中,有的线程会开始执行了。
	            results.add(executor.submit(new Callable<Long>() {  
	                @Override  
	                public Long call() throws Exception {  
	                        long begin = System.currentTimeMillis();
	                			try {
	                				//测试对象,如向数据库插入数据
	                				//test.insert();

	                			} catch (Exception e) {
	                				e.printStackTrace();
	                			}	                		
	                        long end = System.currentTimeMillis();  
	                    return end - begin;  
	                }  
	            }));  
	        }  
	        
	        // void shutdown()平滑关闭,停止接受任何新的任务且等待已经提交的任务执行完成(已经在执行的和还没有开始执行的)
	        //  List<Runnable>	shutdownNow()强制关闭,  试图停止当前正执行的task,并返回尚未执行的task的list 
	        executor.shutdown();  
          //线程等待timeout时长,当超过timeout时间后,会监测ExecutorService是否已经关闭,若关闭则返回true,否则返回false。
	        while(!executor.awaitTermination(1, TimeUnit.MINUTES)){
	        	System.out.println("线程池没有关闭");   
	        }
	        System.out.println("线程池已经关闭");     
	        long sum = 0;  
	        for (Future<Long> result : results) {  
	            sum += result.get();  
	        } 
	        System.out.println("running time: " + sum + "ms");  

 

 三、其它

什么代码是始终为线程安全的、是不需要同步的。如下:

1)常量始终是线程安全的,因为只存在读操作。

2)对构造器的访问(new 操作)是线程安全的,因为每次都新建一个实例,不会访问共享的资源。

3)最重要的是:局部变量是线程安全的。因为每执行一个方法,都会在独立的空间创建局部变量,它不是共享的资源。局部变量包括方法的参数变量。

 

 

分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics