`

Java多线程——synchronized的问题

 
阅读更多

一直以来都存在这样的问题:

多线程操作同一对象。该对象有一个方法为m1,另一个方法为m2,那么当有一条线程执行m1时,同时该线程获得该对象的锁。那么另一个线程能否调用m2呢?

 

试验代码1:

public class ThreadSafeObject {
	public int i=0;
	public synchronized void add(){
		System.out.println(Thread.currentThread().getName()+";开始调用safeObject的add()方法,调用之前的值为:"+i);
		System.out.println("add方法执行5s");
		try {
			Thread.sleep(5000);
		} catch (InterruptedException e) {
			e.printStackTrace();
		}
		i++;
		System.out.println(Thread.currentThread().getName()+";开始调用safeObject的sub()方法,调用之后的值为:"+i);
	}
	
	public synchronized void sub(){
		System.out.println(Thread.currentThread().getName()+";开始调用safeObject的sub()方法,调用之前的值为:"+i);
		System.out.println("sub方法执行1s");
		try {
			Thread.sleep(1000);
		} catch (InterruptedException e) {
			e.printStackTrace();
		}
		i--;
		System.out.println(Thread.currentThread().getName()+";开始调用safeObject的sub()方法,调用之后的值为:"+i);
		
	}
	
}

 

public class TestThreadAdd  implements Runnable{
	ThreadSafeObject safeObject ;
	
	public TestThreadAdd(ThreadSafeObject safeObject){
		 this.safeObject = safeObject;
	}
	
	@Override
	public void run() {
		System.out.println(Thread.currentThread().getName()+",开始执行。");
		safeObject.add();
		System.out.println(Thread.currentThread().getName()+",结束执行。");
		
	}
	
}

 

public class TestThreadSub  implements Runnable{
	ThreadSafeObject safeObject ;
	
	public TestThreadSub(ThreadSafeObject safeObject){
		 this.safeObject = safeObject;
	}
	
	@Override
	public void run() {
		System.out.println(Thread.currentThread().getName()+",开始执行。");
		safeObject.sub();
		System.out.println(Thread.currentThread().getName()+",结束执行。");
	}
	
}

 

public class Main {
	public static void main(String[] args) throws InterruptedException {
		ThreadSafeObject threadSafeObject = new ThreadSafeObject();
		
		new Thread(new TestThreadAdd(threadSafeObject)).start();
		Thread.sleep(200);
		new Thread(new TestThreadSub(threadSafeObject)).start();
		
	}
}

该代码段的执行结果如下:

Thread-0,开始执行。
Thread-0;开始调用safeObject的add()方法,调用之前的值为:0
add方法执行5s
Thread-1,开始执行。
Thread-0;开始调用safeObject的sub()方法,调用之后的值为:1
Thread-1;开始调用safeObject的sub()方法,调用之前的值为:1
sub方法执行1s
Thread-0,结束执行。
Thread-1;开始调用safeObject的sub()方法,调用之后的值为:0
Thread-1,结束执行。

 

可以看到当Thread-0执行了5s的add()方法后,Thread-1才能执行sub()方法。

可见,当Thread-0没有执行完add()方法之前,Thread-1是被阻塞的,且是没有获取线程锁的方式阻塞。

 

 

 

试验代码2:

把ThreadSafeObject的sub()方法的synchronized去掉。

public class ThreadSafeObject {
	......
	
	public /*synchronized*/ void sub(){
                ......
		
	}
	
}

 执行结果如下:

Thread-0,开始执行。
Thread-0;开始调用safeObject的add()方法,调用之前的值为:0
add方法执行5s
Thread-1,开始执行。
Thread-1;开始调用safeObject的sub()方法,调用之前的值为:0
sub方法执行1s
Thread-1;开始调用safeObject的sub()方法,调用之后的值为:-1
Thread-1,结束执行。
Thread-0;开始调用safeObject的sub()方法,调用之后的值为:0
Thread-0,结束执行。

 

可以看到:Thread-1没有等Thread-0的执行结束。即Thread-1不需要去获取共有对象的锁。

 

 

试验结论

synchronized关键字是强制线程获取对象的锁标志。如果没有该关键字,则线程不去等待锁的获取,而直接操作对象。

 

分享到:
评论

相关推荐

    Java多线程——线程八锁案例分析.docx

    在Java多线程编程中,线程安全是一个关键概念,特别是在并发访问共享资源时。"线程八锁案例分析"文档中的示例着重展示了`synchronized`关键字如何在控制线程同步方面发挥作用。以下是对这些案例的详细分析: 案例1...

    JAVA多线程——一篇文章让你彻底征服多线程开发.docx

    ### JAVA多线程详解 #### 一、线程与进程的概念 在计算机科学中,**进程**是指一个正在运行的应用程序或程序实例,而**线程**则是进程中可并发执行的一部分,是进程内的一个执行流。一个进程可以拥有多个线程,这些...

    java多线程教程——一个课件彻底搞清多线程

    Java多线程是Java编程中的核心概念,它允许程序同时执行多个任务,从而提高应用程序的效率和响应性。本教程将深入讲解Java线程的相关知识,包括进程与线程的基本概念、线程的创建和启动、多线程的互斥与同步、线程...

    java多线程案例——未完成

    Java多线程是Java编程中的一个重要领域,它允许程序同时执行多个任务,从而提高系统效率和资源利用率。在这个未完成的案例中,我们可能正在探讨如何在Java中创建和管理线程,以及处理多线程环境下的并发问题。下面是...

    【后端】 java基础(5.8)java高级基础之线程——synchronized关键字

    java基础(5.8)java高级基础之线程——synchronized关键字 本章主要讲线程,至于带上进程的原因是为了方便大家对进程和线程有个概念(咳,主要原因是鄙人也不太会进程~)。 首先简单说下我个人对进程和线程的理解。...

    java多线程设计模式详解(PDF及源码)

    去睡觉吧 第11章 Thread-Specific Storage——每个线程的保管箱 第12章 Active Object——接受异步消息的主动对象 总结 多线程程序设计的模式语言 附录A 练习问题的解答 附录B Java的内存模型 附录C Java线程的...

    Java多线程的小例子——吃包子

    这个名为"Java多线程的小例子——吃包子"的示例,旨在帮助开发者直观地理解多线程的工作原理。下面我们将深入探讨该示例所涉及的核心知识点。 首先,多线程通常涉及到以下几个关键概念: 1. **线程(Thread)**:...

    java上机报告5——Java的多线程编程1

    Java 多线程编程应用场景 —— 电影院售票系统设计 本资源摘要信息将对 Java 多线程编程在电影院售票系统设计中的应用进行详细介绍。该系统模拟了电影院三个售票窗口同时出售电影票的过程,通过 Java 多线程编程...

    java多线程设计

    本知识点将深入探讨Java多线程设计以及如何利用“不可变对象”(immutable objects)来避免多线程环境中的非安全问题。 一、Java多线程基础 1. 线程的创建:Java提供了两种创建线程的方式——继承Thread类和实现...

    JAVA项目——多线程下载代码

    下面我们将深入探讨相关的Java多线程下载知识点。 1. **线程基础**:在Java中,线程是程序执行的最小单元,每个线程负责一部分任务。在多线程下载中,每个线程负责下载文件的一个部分。 2. **Thread类与Runnable...

    JAVA并发多线程的面试问题及答案-java多线程并发面试题.docx

    在这里,我们将从面试的角度列出了大部分重要的问题,但是你仍然应该牢固的掌握Java多线程基础知识来对应日后碰到的问题。 1. 多线程和并发问题 在 Java 中,多线程和并发问题是非常重要的。面试官通常会问一些...

    Java——多线程编程技术.pdf

    Java多线程编程技术的同步机制是通过Synchronized关键字和Volatile关键字来实现的。Synchronized关键字可以使线程之间同步执行,而Volatile关键字可以使线程之间共享变量。 Java多线程编程技术的应用场景非常广泛,...

    Java多线程编程详解

    综上所述,Java多线程编程不仅提供了强大的并发执行能力,同时也带来了复杂度更高的问题,需要开发者深入了解并妥善处理。掌握Java多线程编程的精髓,将为构建高性能、高可用性的应用打下坚实的基础。

    java 多线程交互简单范例

    这个压缩包中的文件提供了几个关于Java多线程交互的实例,可以帮助我们深入理解如何在并发环境中控制线程的同步,确保数据的一致性和安全性。 首先,让我们讨论一下标题和描述中提到的关键概念——“多线程交互”和...

    java线程应用——排序过程动态显示

    这通常涉及到两种主要技术:多线程和图形用户界面(GUI)的实时更新。在Java中,我们可以使用`Thread`类或`Runnable`接口来创建和管理线程,而`Swing`或`JavaFX`库则可以用于构建GUI。 1. **线程创建与运行**: - ...

    java多线程的使用和介绍

    ### Java多线程的使用与介绍 #### 什么是多线程? 多线程是指程序能够同时执行多个线程的能力。每个线程都是一个轻量级的进程,可以在单个程序中独立运行,共享该程序的资源。在Java中,多线程是通过`java.lang....

    Java多线程下载网络图片

    在Java编程中,多线程是一项关键技能,尤其在处理并发任务时,如我们的示例——"Java多线程下载网络图片"。这个场景展示了如何利用多线程技术提高程序性能,减少用户等待时间,同时优化系统资源的使用。下面我们将...

    Java 语法总结——线程(线程)

    这种设计使得多线程环境下的资源利用更为高效。 二、线程的创建 1. 实现Runnable接口:创建一个类实现Runnable接口,重写run()方法。然后通过Thread类的构造函数传入Runnable实例来创建线程,例如: ```java class ...

    java多线程学习资料

    ### Java多线程学习资料知识点解析 #### 一、引言 Java作为一种广泛使用的编程语言,在并发编程领域具有独特的优势。多线程是Java中实现并发处理的核心技术之一,能够显著提升程序的性能和响应性。本文将深入探讨...

    java葵花宝典——各种问题详细解答

    《Java葵花宝典——各种问题详细解答》 在编程世界中,Java以其跨平台、面向对象、稳定性和高效性而备受青睐。本资源“Java葵花宝典”旨在为初学者和经验丰富的开发者提供一系列关于Java的常见问题解答,以及深入...

Global site tag (gtag.js) - Google Analytics