`
sulifeng
  • 浏览: 40913 次
  • 性别: 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变量进行赋值和读取.
分享到:
评论

相关推荐

    Java 并发核心编程

    Java提供了多种机制来实现这一点: 1. **Wait/Notify**: `Object.wait()`和`Object.notify()`用于线程之间的简单同步。 2. **CountDownLatch**: 允许一个或多个线程等待其他线程完成一组操作。 3. **CyclicBarrier*...

    java深入理解多线程

    以下是对Java多线程的深入理解: 线程概述 基本概念:线程是操作系统能够进行运算调度的最小单位,一个进程可以包含多个线程。 特性:线程不拥有系统资源,只拥有一点必不可少的、能保证独立运行的资源。同一进程...

    Lock、Synchoronized和ReentrantLock的使用

    Synchronized 的优点是易于使用和理解,编译器通常会对其进行优化,可以提高性能。然而,Synchronized 也有一些缺点,如它不能被Interrupt,且在资源竞争激烈的情况下性能会下降。 二、ReentrantLock ...

    JAVA自学笔记,一点一点积累的!

    - **线程同步**:理解synchronized关键字,死锁、活锁的概念,以及wait()、notify()、notifyAll()的使用。 - **线程池**:学习ExecutorService,ThreadPoolExecutor和Future接口的使用。 7. **网络编程**: - **...

    Java 多线程同步 锁机制与synchronized深入解析

    线程获取锁的顺序是不确定的,Java规范中并未保证这一点。线程调度的细节由JVM决定,可能存在一定的非确定性。 同步代码块提供了更多的灵活性。它可以指定锁定的对象,这就像是用不同房子的钥匙打开同一个房子的...

    一点课堂 JAVA核心知识点整理.zip

    理解线程的创建(Thread类或Runnable接口)、线程同步(synchronized关键字、wait()、notify()、notifyAll()方法)、线程池(ExecutorService)以及并发集合(如ConcurrentHashMap)等概念,对于编写高效、安全的多...

    JavaLock与Condition的理解Reentran

    公平锁按照线程等待的顺序分配锁,而非公平锁则不保证这一点。默认情况下,ReentrantLock是非公平的,可以通过构造函数传入`true`来创建公平锁。 四、Condition接口 Condition接口是与Lock配套使用的关键组件,它...

    synchronized_trackball_flutter_chart:Flutter图表中的同步轨迹球

    在Flutter中实现这样的功能,需要对以下知识点有深入的理解: 1. **Dart语言**:Dart是Flutter的开发语言,它提供了面向对象、函数式和命令式编程的特性。在开发这个特性时,你需要熟悉Dart的类、对象、异步处理...

    Java初学者都必须理解的六大问题.

    理解线程同步的概念,如`synchronized`关键字、`wait()`、`notify()`和`notifyAll()`方法,以及死锁和活锁等并发问题,是编写高效并发程序的关键。 理解这些问题对于Java初学者至关重要,它们涵盖了对象、字符串...

    Java面试宝典

    4. **多线程**:理解线程的创建方式(实现Runnable、继承Thread),掌握同步机制(synchronized、wait/notify、ReentrantLock),了解死锁、活锁、饥饿状态,以及线程池的使用。 5. **异常处理**:理解Checked和...

    04 并发编程专题07.zip

    首先,synchronized是Java内置的一种同步机制,用于控制对共享资源的多线程访问。它提供了两种使用方式:修饰实例方法和修饰代码块。当一个线程进入一个由synchronized修饰的方法或代码块时,其他试图访问相同同步...

    设计模式一点通之单态模式

    2. **违背了开闭原则**:对修改关闭,对扩展开放,单例模式做不到这一点。 总的来说,单态模式是一种常见的设计模式,它在许多场景下能提供简洁有效的解决方案,但也需要谨慎使用,以避免过度设计和潜在的问题。...

    geek学习 有空就学习一点啦

    6. 多线程:并发编程,理解Thread类和Runnable接口,以及同步机制(synchronized关键字,wait()和notify())。 7. Java Swing和JavaFX:用于构建图形用户界面(GUI)的库。 8. Java EE:企业级应用开发,包括Servlet...

    一点Java复习资料

    - 多线程:线程的创建、同步机制(synchronized关键字、wait/notify机制)、线程池。 - 输入/输出流:字节流和字符流,文件操作,对象序列化。 - 内存管理:堆和栈内存的区别,垃圾回收机制,对象引用的理解。 -...

    Lock详解.pdf

    通过对AQS的剖析,我们将揭示ReentrantLock如何实现其独特的特性和功能,以及它与synchronized关键字的异同。 ReentrantLock是Java.util.concurrent包下的一个类,它是基于AQS框架实现的线程同步机制。与...

    java入门教程:数据类型_Java理论与实践如何正确使用Volatile变量.docx

    这意味着其他线程无需再次获取锁即可看到最新的值,这一点与`synchronized`关键字有所不同,后者除了提供可见性之外还确保了操作的原子性。 #### Volatile与Synchronized的比较 尽管`volatile`变量提供了一定程度的...

    java学习笔记来自java黑马B站网课,没有图片 看不了一点

    线程同步机制,如synchronized关键字、wait()、notify()和notifyAll()方法,用于避免多线程环境下的数据竞争问题。 Java标准库(JDK)提供了丰富的API,例如Swing和JavaFX用于创建图形用户界面,JDBC用于数据库连接...

    学习java的积点忽略之处

    理解synchronized、volatile、ThreadLocal等关键字的含义,以及死锁、活锁等问题,是提升程序效率和稳定性的关键。 7. **IO流**:Java的IO流体系庞大,初学者可能只停留在基础的文件读写上,忽视了NIO(非阻塞I/O)...

    多线程面试专题及答案

    在Java编程领域,多线程是面试中常见且重要的知识点,尤其对于...以上内容涵盖了Java多线程的各个方面,理解和掌握这些知识点,将对你的Java面试和实际开发大有裨益。深入学习和实践,才能在多线程的世界里游刃有余。

    java面试题(100道)

    以上只是对Java面试题可能涵盖的知识点的概览,每一点都可以深入探讨,理解并掌握这些知识点将有助于你在面试中展现出扎实的技术功底。准备面试时,不仅要理解和记忆这些知识,还要尝试通过实际编码来加深理解,做到...

Global site tag (gtag.js) - Google Analytics