`

黑马程序员--java基础复习--线程--同步与通信

 
阅读更多



 

 ---------------------- ASP.Net+Android+IO开发S.Net培训、期待与您交流! ---------------------

  单个线程操作资源的时候,是不会出现安全问题的,但是如果多个线程操作同一个资源的时候,因为CPU的使用权限是大家平等的,在任何时候都可能执行任意线程的任意语句(在不加锁的情况下),这就会产生线程的安全问题,比如下边代码

package thread;

public class TestThread {
	private static int count;

	int line = 5;

	public static void main(String[] args) {
		TestThread tt = new TestThread();
		tt.startThread();
		tt.startThread();
	}

	class CountThread implements Runnable {
		public void run() {

			while (count < 25) {
				//synchronized (TestThread.class) {
					//if(count < 25){
						count++;
						System.out.print(Thread.currentThread().getName() + "--" + count + "\t");
						line--;
						if (line == 0) {
							System.out.println();
							line = 5;
						}
					}					
				//}				
			//}
		}
	}
	
	public void startThread() {
		new Thread(new CountThread()).start();
	}
}

 

 运行结果为:

 Thread-0--1 Thread-0--3 Thread-0--4 Thread-0--5 Thread-0--6 
Thread-0--7 Thread-0--8 Thread-0--9 Thread-0--10 Thread-1--2 
Thread-1--12 Thread-1--13 Thread-1--14 Thread-1--15 Thread-1--16 
Thread-1--17 Thread-1--18 Thread-1--19 Thread-1--20 Thread-1--21 
Thread-1--22 Thread-1--23 Thread-1--24 Thread-0--11 Thread-1--25 

 

明显不符合我们的程序初衷,中间的2无缘无故没了,这就是线程的安全问题了,所以要加入控制代码同步的锁,如下代码

package thread;

public class TestThread {
	private static int count;

	int line = 5;

	public static void main(String[] args) {
		TestThread tt = new TestThread();
		tt.startThread();
		tt.startThread();
	}

	class CountThread implements Runnable {
		public void run() {

			while (count < 25) {
				synchronized (TestThread.class) {
					if(count < 25){
						count++;
						System.out.print(Thread.currentThread().getName() + "--" + count + "\t");
						line--;
						if (line == 0) {
							System.out.println();
							line = 5;
						}
					}					
				}				
			}
		}
	}
	
	public void startThread() {
		new Thread(new CountThread()).start();
	}
}

 运行结果就为:

Thread-0--1 Thread-1--2 Thread-1--3 Thread-1--4 Thread-1--5 
Thread-1--6 Thread-0--7 Thread-0--8 Thread-0--9 Thread-0--10 
Thread-0--11 Thread-0--12 Thread-0--13 Thread-0--14 Thread-0--15 
Thread-0--16 Thread-0--17 Thread-0--18 Thread-0--19 Thread-0--20 
Thread-1--21 Thread-1--22 Thread-1--23 Thread-0--24 Thread-0--25 

这才是正常的,在程序代码中使用了两次判断count<25,这是因为这样可以让多个程序同时访问count,而不用等别的程序的while循环结束。

同步代码用的锁是一个对象,而且需要同步的代码所用的锁必须是一样的。

(转自CSDN) 

  • 同步代码块定义方法:
    • synchronized(对象)//这个对象可以是任意对象,例如Object,这样做是为了减小锁的粒度,建议使用更经济的空byte数组对象做锁。
      • //对象如同锁,持有锁的线程可以在同步中执行。没有锁的线程即使获取CPU的执行权,也进不去,因为没有获取锁。
    • {
      • 需要被同步的代码//这个代码不包括共享数据,只包括判断与结论等不能分割的数据。
    • }
  • 同步的前提:
    • 必须有两个或以上的线程。
    • 必须是多个线程使用同一个锁。必须保证同步中只能有一个线程在运行。
  • 同步的好处:
    • 解决了多线程的安全问题。
  • 同步的弊端:
    • 多个线程需要判断锁,较为消耗资源。
  • 哪些时候使用同步?
    • 1.明确哪些代码是多线程运行代码。
    • 2.明确共享数据。
    • 3.明确多线程运行代码中哪些语句是操作共享数据的。

(转自CSDN) 

另外,在函数的返回值类型前加上 synchronized声明,则成为同步函数,和同步代码块一个效果

 

上面的例子只是做到了同步,但是当多个线程对同一资源进行不同操作是,单是同步并不够,因为每个线程的运行条件不一样,比方说对一个仓库的操作,一个往里边加东西的线程需要判断里边有没有装满,一个从里边拿东西的线程则需要判断里边有没有东西,这两个判断都是基于仓库中的资源,所以需要同步,但是如果仓库满的话,那放东西的线程就必须休息一下,即是wait,那它什么时候醒呢?当然是有人叫醒它了,叫醒它的人就是和它有同样同步锁的拿东西的那个线程了,这就是线程的通信基本原理

  通信的时候需要注意的问题:

  1. 有三个以上的线程的时候,判断是否休息的语句用while,因为用if可能会让所有线程等待,if只判断一次。
  2. 有三个以上的线程的时候,叫醒用notifyAll,这样会避免叫醒的线程正好是和要去睡觉的线程是同一类,然后大家都睡觉了。

这里边的关系用一幅图来表示吧



 

当然这是最背的情况,实际情况更复杂,需要用配合代码来说明的。

 

---------------------- ASP.Net+Android+IOS开发.Net培训、期待与您交流! ----------------------

详细请查看:http://edu.csdn.net

  • 大小: 29.5 KB
  • 大小: 3.2 KB
分享到:
评论

相关推荐

    黑马程序员-Java语言进阶-源码、教程笔记.zip

    day01_Object类、常用API day02_Collection、泛型 day03_List、Set、数据结构、Collections day04_Map,斗地主案例 day05_异常,线程 day06_线程、同步 day07_等待与唤醒案例、线程池、Lambda...Java基础小节练习题答案

    黑马程序员-java多线程技术01

    本教程将聚焦于Java中的多线程技术,以“黑马程序员-java多线程技术01”为学习起点,探讨如何在Java中实现并管理线程。 首先,我们来理解什么是线程。线程是操作系统分配CPU时间的基本单元,一个进程中可以有多个...

    黑马程序员-Qt讲义.pdf

    Socket通信是网络编程中不可或缺的技术,Qt支持基于TCP/IP协议的客户端和服务器端编程,以及UDP通信和组播技术。 多线程是现代应用程序中用来提高性能的重要技术。Qt提供了多线程编程的支持,包括线程的基本概念...

    传智播客.黑马程序员《Java 基础入门》课后习题答案

    《Java 基础入门》课后习题答案 第 第 1 章 Java 开发入门 一、填空题 1、 Java EE、Java SE、Java ME 2、 JRE 3、 javac 4、 bin 5、 path、classpath 二、选择题 1、ABCD 2、C 3、D 4、B 5、B 三、简答题 1、 面向...

    01_黑马程序员_张孝祥_Java基础加强_课程价值与目标介绍.zip

    【标题】"01_黑马程序员_张孝祥_Java基础加强_课程价值与目标介绍.zip" 提供的是一门由黑马程序员机构推出的Java基础强化课程,由讲师张孝祥主讲,旨在深入讲解Java编程的基础知识并进行能力提升。 【描述】中提到...

    黑马程序员入学Java精华总结

    ### 黑马程序员入学Java精华总结 #### 一、Java概述与基础知识 1. **何为编程?** - 编程是指通过编写计算机能够理解的指令来解决问题或完成特定任务的过程。这些指令通常被组织成算法,并使用某种编程语言实现。...

    黑马程序员_张孝祥_Java多线程与并发库 视频+代码+资料

    根据给定文件的信息,我们可以提炼出以下关于Java多线程与并发库的相关知识点: ### Java多线程基础 1. **线程的概念**:在Java中,线程是程序执行流的基本单元。一个标准的Java应用程序至少有一个线程,即主...

    Java基础案例教程(第2版)_PPT.zip

    《Java基础案例教程(第2版)》是一本旨在教授初学者Java编程基础知识的教材,其PPT形式的压缩包提供了清晰、直观的教学材料。在深入探讨这些知识点之前,我们首先了解一下Java语言的基础概念。 Java是一种面向对象...

    黑马程序员java基础试题、笔记

    "黑马程序员java基础试题、笔记"这个压缩包资源为Java初学者和希望加入"黑马程序员"培训课程的学员提供了丰富的学习材料。这些资源包括面试问题合集、整理的资料、Android面试题、学员入学面试总结、面试技巧、必须...

    黑马程序员面试宝典(java)2018版

    《黑马程序员面试宝典(java)2018版》是一本专门为Java开发者准备的面试指南,涵盖了大量在面试过程中可能遇到的问题和知识点。这本宝典由黑马程序员机构精心编纂,汇集了近万名学员的实际面试经验,为求职者提供了...

    计算机后端-Java-Java核心基础-第21章 常用类 03. 复习:线程通信和新的线程创建方式等.avi

    计算机后端-Java-Java核心基础-第21章 常用类 03. 复习:线程通信和新的线程创建方式

    黑马程序员毕向东java基础课堂完整版文档

    5. **多线程**:介绍线程的创建与同步,包括Thread类和Runnable接口,以及synchronized、wait、notify关键字的使用。 6. **网络编程**:讲解Socket编程的基本原理和应用,以及URL、URLConnection的使用。 此外,...

    黑马程序员_张孝祥_Java多线程与并发库

    黑马程序员_张孝祥_Java多线程与并发库,老师讲的非常仔细,老师很有耐心.欢迎大家下载学习.

    2023黑马面试宝典-Java面试宝典大全-java面试宝典黑马

    Java面试宝典是Java程序员求职面试的重要参考资料,它涵盖了Java编程语言的核心概念、高级特性、设计模式、并发处理、框架应用、数据库交互等多个方面。以下将详细解析这些关键知识点: 1. **Java基础**:面试中,...

    Java基础案例教程(第2版)-课后习题答案.zip

    8. **多线程**:Java支持多线程编程,习题可能包括创建线程、同步机制(synchronized关键字和wait/notify方法)以及线程池的使用。 9. **文件和目录操作**:Java的File类和nio包提供了丰富的API用于操作文件和目录...

    黑马程序员java面试宝典 完整版PDF.rar

    《黑马程序员Java面试宝典》是一本...通过《黑马程序员Java面试宝典》的学习,你可以系统地复习和掌握这些知识点,提高自己的面试竞争力。书中的问题和解答将帮助你更好地理解Java编程的本质,提升在面试中的自信心。

    《Java基础案例教程(第2版)》课后习题答案1

    这些知识点是Java初学者需要掌握的基础,深入理解和熟练运用这些知识是成为合格的Java程序员的第一步。在实际编程中,还需要学习异常处理、集合框架、IO流、网络编程、多线程高级特性以及设计模式等更多内容。

    Java基础案例教程(第2版)-教学设计.zip

    学生将学习线程的创建、同步、通信以及线程池的使用,理解线程安全和死锁问题。 最后,Java基础案例教程可能还会涵盖Java Swing或JavaFX图形用户界面(GUI)开发,让学生了解如何创建桌面应用程序。 通过《Java...

    黑马程序员入学面试题

    同步函数与同步代码块的区别 - **同步函数**:整个函数都是同步的,即加了`synchronized`关键字的方法。 - **同步代码块**:只对代码块内的代码进行同步,使用`synchronized`关键字加括号的方式。 #### 22. 数组和...

    计算机后端-Java-Java核心基础-第20章 多线程 02. 复习:IDEA使用与多线程基本概念.avi

    计算机后端-Java-Java核心基础-第20章 多线程 02. 复习:IDEA使用与多线程基本概念.avi

Global site tag (gtag.js) - Google Analytics