Java 多线程序的一点理解

synchronized 是java 内主要的同步标记

1 同步非静态方法

  作用域范围只是当前对象在不同线程间的同步, 如果n 为Test外的对象,在不同的Test对象之间,等于没有同步, 该方法只能同步n为Test类内对象

       

public class Test	
public  synchronized void inc() {
			n++;
		}
}

  如果想同步类外的n,使用同步代码块对象,对象也为一个类外对象,相对所有Test对象来说, 也只有一个,所以就能同步

final Integer lock = new Integer(1);
	class Test  implements Runnable {
		public int value = 0;
		public  void inc() {
			synchronized (lock) 
			{
				m++;
				value++;
				n++;
			}
		}

  

2  同步静态方法

  

public class Test	
public  static synchronized void inc() {
			n++;
		}
}

  作用域范围是所有Test类对象,  inc方法在所有Test对象之间只能被一个同时调用

3  同步代码块 

 

publci class Test{
     public  void inc() {
			synchronized (lock) 
			{
				// m++;
				value++;
				n++;
			}
		}
}

  

  作用域范围,取决于lock的相对该类的作用域范围

如果lock 是该类以外的对象,相对所有的Test 对象而言,  lock是个全局变量,  synchronized同步范围在所有对象之间

如果lock 是该类以内的对象,如类内变量,相对所有的Test 对象而言,  lock是个本地局部变量,  synchronized同步范围在同一对象的不同线程之间, 和同步非静态方法一样

测试代码

import java.util.concurrent.CountDownLatch;
import java.util.concurrent.CountDownLatch;

public class TestVolatile {
	public static volatile int  n = 0; // 
	public  Integer m = 0;
	final Integer lock = new Integer(1);

	class MyThread implements Runnable {
		public int value = 0;
		public  void inc() {
			synchronized (lock) 
			{
				m++;
				value++;
				n++;
			}
		}

		public void run() {

			{
				for (int i = 0; i < 1000; i++)
					try {
						// System.out.println(i);
						inc();
						// m++;
						// vboolean = vboolean == true ? false : true;
						Thread.sleep(3); // 为了使运行结果更随机,延迟3毫秒
					} catch (Exception e) {
					}
			}
		}
	}

	static class MyThread1 implements Runnable {
		public static Integer locallock = new Integer(2);
		public static synchronized void inc() {
			n++;
		}

		public  void run() {
			for (int i = 0; i < 1000; i++)
				try {
					//inc();  方法一
					
					// 方法二 
					synchronized (locallock){ 
					    n = n + 1;
				}
					Thread.sleep(3);
				} catch (Exception e) {
				}
		}
	}

	class MyThread2 implements Runnable {
		public void run() {
			synchronized (lock) {
				for (int i = 0; i < 100; i++)
					try {
						m++;
						Thread.sleep(3); // 为了使运行结果更随机,延迟3毫秒
					} catch (Exception e) {
					}
			}
		}
	}
    
	// 3和2代码一样,只是一个是分开锁, 一个只是单独加锁, 效率相差10倍左右。
	class MyThread3 implements Runnable {
		public void inc() {
			synchronized (lock) {
				m++;
			}
		}

		public void run() {
			for (int i = 0; i < 1000; i++)
				try {
					inc();
					Thread.sleep(3); // 为了使运行结果更随机,延迟3毫秒
				} catch (Exception e) {
				}
		}
	}
	
	public Value g_value = new Value();
	public class Value{
		public synchronized void inc() 
		{
			m++;
		}
	}
    
	// 4和3功能差不多,只是 MyThread4, 使用全局变量g_value 的锁,不同线程间同步
	class MyThread4 implements Runnable {
		public int value = 0;
		public  void inc() {
			{
				g_value.inc();
			}
		}

		public void run() {
				for (int i = 0; i < 1000; i++)
					try {
						inc();
						Thread.sleep(3); // 为了使运行结果更随机,延迟3毫秒
					} catch (Exception e) {
					}
			}
	}

	public void runthread() throws InterruptedException {
		long beg = System.currentTimeMillis();
		MyThread1[] mythreadary = new MyThread1[100];
		Thread[] threadary = new Thread[100];
		for (int i = 0; i < threadary.length; i++) {
			mythreadary[i] = new MyThread1();
			threadary[i] = new Thread(mythreadary[i], "test1");
		}

		for (int i = 0; i < threadary.length; i++) {
			threadary[i].start();
		}

		for (int i = 0; i < threadary.length; i++) {
			threadary[i].join();
		   // System.out.println((mythreadary[i]).value);
		}

		System.out.println(TestVolatile.n);
		System.out.println(m);

		System.out.println("程序耗时: " + (System.currentTimeMillis() - beg));
	}

	public static void main(String[] args) throws InterruptedException {
		TestVolatile tmp = new TestVolatile();
		tmp.runthread();
	}
}

  

posted @ 2014-10-08 08:31  谭志宇  阅读(320)  评论(0编辑  收藏  举报