`
sulifeng
  • 浏览: 39998 次
  • 性别: Icon_minigender_1
  • 来自: 西安
社区版块
存档分类
最新评论

对synchronized的一点理解

    博客分类:
  • Java
阅读更多
    对synchronized的一点理解.源程序来自马士兵老师的视频教程.
   
    下面这个程序中,num变量刚开始的值为0, t1执行num++后, num变为1,然后t1开始休眠,
t2开始执行,也执行num++,将num变为2, t1休眠完毕,读取到的num变量值为2,t2休眠完后读取到的num变量值为2, 于是就有了类似于"丢失更新"的问题.
public class TongBuTest implements Runnable {
	Timer timer = new Timer();

	public static void main(String[] args) {
		TongBuTest test = new TongBuTest();

		Thread t1 = new Thread(test);
		Thread t2 = new Thread(test);
		t1.setName("t1");
		t2.setName("t2");
		t1.start();
		t2.start();
	}

	public void run() {

		timer.add(Thread.currentThread().getName());
	}

}

class Timer {
	int num = 0;

	public   void add(String name) {
		{	
			num++;
			try {
				Thread.sleep(1);
			} catch (InterruptedException e) {

			}
			System.out.println(name + ",你是第" + num + "个使用本方法的线程!");
		}
	}
}

    上述代码运行结果:
  
t1,你是第2个使用本方法的线程!
t2,你是第2个使用本方法的线程!


    在add方法前加上sychronized关键字就能避免这个问题.加上sychronized之后的运行结果为:

t1,你是第1个使用本方法的线程!
t2,你是第2个使用本方法的线程!

  


   再看下面这段代码:
   
public class TT implements Runnable {

	int b = 100;

	public  synchronized void m1() throws InterruptedException {
		 {
		  b = 1000;
		  Thread.sleep(2000);
		  System.out.println("b=" + b);
		}
	}
	public void m2() {
		b=1111; 
		System.out.println(b);
	}

	public void run() {
		try {
			m1();
		} catch (Exception e) {
			e.printStackTrace();
		}

	}

	public static void main(String[] args) throws InterruptedException {
		TT t = new TT();
		Thread thread = new Thread(t);
		thread.start();

		 
		Thread.sleep(1000);
		 
		t.m2();

	}

}

    运行结果是:
1111
b=1111

    我个人的理解是, synchronized只是锁住了语句,使得某一段代码在任意时刻只被一个线程执行, 它并不能锁住这段代码内所涉及的变量资源.
    在TongBuTest.java中,加上synchronized关键字后,num++被锁住,t1执行完并输出num值之后才允许t2执行add方法.
    在TT.java中, m1方法有synchronized关键字,m1方法体内的所有代码被锁住,但是b这个变量并没有被锁住,所以允许m2方法对b变量进行赋值和读取.
分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics