`
heipark
  • 浏览: 2097473 次
  • 性别: Icon_minigender_1
  • 来自: 北京
社区版块
存档分类
最新评论

Java多线程并发学习笔记

 
阅读更多

《Java Concurrency in Practice》学习笔记:

 

Q:Thread.sleep()方法什么时候触发InterruptedException?

A:线程执行start()方法启动后,当执行sleep()方法的时候,线程又执行了interrupt()方法,会触发InterruptedException()

 

 

public class MultiThreadTest extends Thread {

	public static void main(String[] args) throws InterruptedException {
		System.out.println("main thread start.");
		Thread t = new MultiThreadTest();
		t.start();
		t.join(2000);
		t.interrupt(); // 这里将出发线程InterruptedException
		System.out.println("main thread end.");
	}

	@Override
	public void run() {
		System.out.println("sub thread start.");
		try {
			Thread.sleep(99999999);
		} catch (InterruptedException e) {
			// 截获InterruptedException
			System.err.println("sub thread 被中断了");
			return;
		}
		System.out.println("sub thread end.");
	}
}
 

 

// 输出结果
main thread start.
sub thread start.
sub thread 被中断了
main thread end.

Q:什么是守护线程?

A:Java有两种Thread:“守护线程(Daemon thread)”与“用户线程”。当虚拟机中将在用户线程结束后退出,如果没有用户线程,守护线程将随虚拟机一同退出。通过调用线程的setDaemon(true)方法设置线程为守护线程。

  servlet原来是线程不安全的

 

下面的servlet用于计算两个输入值的乘机,打开两个浏览器,分别快速输入地址:

 

http://localhost:8888/xxxx/a=2&b=3

http://localhost:8888/xxxx/a=1&b=55

 

结果会发现两个浏览器输出的值是一样的,都是首先打开网址的结果。

 

 

public class TestServlet extends HttpServlet{

	private static final long serialVersionUID = 1L;
	
	int result;
	
	@Override
	protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
		Integer a = Integer.parseInt(req.getParameter("a"));
		Integer b = Integer.parseInt(req.getParameter("b"));
		
		if(a!=null && b != null){
			result = a * b;
		}
		try {
			Thread.sleep(5000);
		} catch (InterruptedException e) {
			e.printStackTrace();
		}
		resp.getWriter().print(result);
	}

}

 

问题:servlet容器复用了servelt实例,当多个线程同时访问这个实例的时候,如果servelt包含实例变量(int result)会发生值被覆盖的情况。

 

解决

 

  1. 干掉实例变量(本例为result),让servlet变成无状态
  2. 使用synchronized关键字,同步方法或者代码块,这样就只有一个线程可以访问同步代码块的内容

 

		synchronized (this) {
			if (a != null && b != null) {
				result = a * b;
			}
			try {
				Thread.sleep(5000);
			} catch (InterruptedException e) {
				e.printStackTrace();
			}
			resp.getWriter().print(result);
		}

 

方法和代码块同步

 

关键字synchronized放在非static方法,则进入该方法需要对象锁;同理进入synchronized (obj){...}的代码块,也需要obj的对象锁

 

举例说明:有一个BankAccount对象,两个线程访问它,一个是存款线程(deposit),一个存款线程(withdraw)

 

 

public class BankAccount {

        // ......

	private int balance;

	public void deposit(int amount) {
		balance = balance + amount;
	}

	public void withdraw(int amount) {
		balance = balance - amount;
	}

}
 

假设初始余额为1000,存款和取款线程各执行10万次,发现结果不确定,可能是几万,或者负数。

 

原因:多线程并发修改一个对象的实例属性时,值会相互影响(覆盖)。

 

解决:使用synchronized 同步临界代码块(critical section)或者同步方法:

 

 

	public void deposit(int amount) {
		synchronized (this) {
			balance = balance + amount;

		}
	}

	public void withdraw(int amount) {
		synchronized (this) {
			balance = balance - amount;
		}
	}
 

 

《Java Concurrency in Practice》  写道
Stateless objects are always thread-safe.
无状态的对象总是线程安全的.

 

 

 写道
Thread-safe classes encapsulate any needed synchronization so that clients need not provide their own.
线程安全的类封装了所有需要同步的代码,所以客户端不需要再进行同步代码
 

 

 

分享到:
评论

相关推荐

    JAVA 多线程学习笔记

    这篇学习笔记将深入探讨Java多线程的核心概念、实现方式以及相关工具的使用。 一、多线程基础 1. 线程与进程:在操作系统中,进程是资源分配的基本单位,而线程是程序执行的基本单位。每个进程至少有一个主线程,...

    笔记_张孝祥_Java多线程与并发库高级应用

    张孝祥Java多线程与并发库高级应用学习笔记,很经典的学习多线程和并发的资料。张孝祥Java多线程讲义笔记由张孝祥亲自整理,很实用的。

    Java并发编程学习笔记 pdf 多线程编程

    Java并发编程学习笔记,研究JAVA并发多线程编程的一本教程,使用并发技术可以开发出并行算法,充分利用多处理器的计算能力,避免硬件资源浪费。目前,在JAVA并发编程方面的论述系统且内容详实的技术资料不太多,Java...

    java多线程笔记

    线程同步是为了避免多线程环境下的数据竞争问题,Java提供了多种同步机制。同步方法通过`synchronized`关键字修饰,确保同一时间只有一个线程能访问该方法。同步块(Synchronized Block)更灵活,可以指定同步的代码...

    多线程学习笔记

    多线程学习笔记 iOS开发中,多线程是一种常见的技术手段,用于优化应用程序的性能,提升用户体验。多线程的核心是让程序能够并发地执行多个任务,合理地利用设备的计算能力,尤其是在拥有多个核心的处理器上。 ...

    张孝祥Java多线程与并发库高级应用笔记

    ### 张孝祥Java多线程与并发库高级应用笔记概览 #### 一、Java多线程技术的重要性与挑战 Java线程技术是软件工程领域不可或缺的一部分,尤其在底层编程、Android应用开发以及游戏开发中,其重要性不言而喻。然而,...

    Java并发编程学习笔记.rar

    这本"Java并发编程学习笔记"可能是作者在深入研究Java并发特性、工具和最佳实践过程中积累的心得体会。下面,我们将根据这个主题,探讨一些关键的Java并发编程知识点。 1. **线程与进程**:在多任务环境中,线程是...

    Java多线程学习笔记

    ### Java多线程学习笔记 #### 一、线程的基本概念 在计算机科学中,**线程**(Thread)是程序执行流的最小单位。一个标准的程序只能做一件事情,而通过多线程技术,可以让程序同时处理多个任务。在Java中,线程是...

    java多线程学习笔记

    这篇文档和源代码将深入探讨Java多线程的各个方面,旨在帮助学习者掌握这一关键技术。 首先,我们要了解Java中创建线程的两种主要方式:继承Thread类和实现Runnable接口。继承Thread类时,我们需要重写run()方法,...

    Java并发编程学习笔记

    Java并发编程是Java开发中必不可少的一部分,涉及到多线程、同步机制、线程池以及并发工具类等多个核心知识点。以下是对这些主题的详细说明: 1. **线程安全与锁 Synchronized 底层实现原理**: 线程安全是指在多...

    Java分布式应用学习笔记05多线程下的并发同步器

    ### Java分布式应用学习笔记05多线程下的并发同步器 #### 1. 前言 在现代软件开发中,特别是在分布式系统和高性能计算领域,有效地管理多线程之间的协同工作至关重要。Java语言提供了丰富的工具和API来帮助开发者...

    java多线程笔记全手打

    本笔记全面涵盖了多线程的学习,包括基础理论和实践代码,旨在帮助开发者深入理解并掌握Java多线程技术。 一、线程基础知识 线程是操作系统分配CPU时间的基本单位,一个进程中可以包含多个线程。Java通过`Thread`类...

    java基础核心学习笔记

    本学习笔记将深入探讨Java的核心概念,帮助你建立坚实的基础。 1. **Java语法基础** - 变量与数据类型:Java支持基本数据类型(如int、float、char)以及引用数据类型(如类、接口、数组)。变量声明必须指定类型...

    Java多线程详解(超详细)_狂神说笔记完整版_项目代码_适合小白随课程学习

    Java多线程详解 在Java编程中,多线程是一种重要的技术,它使得程序能够同时执行多个任务,提高系统的效率和响应性。本教程将详细讲解Java中的多线程概念,包括线程的创建、状态、同步以及高级主题,旨在帮助初学者...

    Java面试题和学习笔记

    Linux面试专题及答案+ActiveMQ消息中间件面试专题+Java基础面试题+MySQL性能优化的21个最佳实践+微服务面试专题及答案+深入理解java虚拟机+设计...专题及答案+java多线程并发编程知识导图笔记+Java并发体系知识导图笔记...

    Java基础 学习笔记 Markdownr版

    本学习笔记主要涵盖了Java的基础知识,包括面向对象、集合、IO流、多线程、反射与动态代理以及Java 8的新特性等方面,旨在帮助初学者或有经验的开发者巩固和提升Java编程技能。 1. 面向对象(OOP):Java的核心是...

    Java并发实践-学习笔记

    在Java编程领域,多线程和并发处理是不可或缺的一部分,特别是在设计高性能、高...通过深入学习这份"Java并发实践-学习笔记",开发者能够提升自己在处理多线程和并发问题上的能力,从而设计出更高效、更稳定的应用。

    Java线程编程学习笔记(二)

    这篇“Java线程编程学习笔记(二)”很可能是对Java并发编程深入探讨的一部分,特别是涉及多线程示例的实践应用。我们将从标题、描述以及标签来推测可能涵盖的知识点,并结合"Multi-Threads Demo"这一压缩包文件名来...

Global site tag (gtag.js) - Google Analytics