`

多线程课程001:线程安全的问题

 
阅读更多
package com.lee.thread;

public class TraditionalThreadSynchronized {

	public static void main(String[] args) {
		//静态方法中不能new内部类的实例对象
		new TraditionalThreadSynchronized().init();
		
	}

	private void init(){
		final Outputer outputer = new Outputer();
		//线程1
		new Thread(new Runnable(){

			@Override
			public void run() {
				while(true){
					try {
						Thread.sleep(10);
					} catch (Exception e) {
						e.printStackTrace();
					}
					outputer.output("zhangxiaoxiang");
				}
			}
			
		}).start();
		
		//线程2
		new Thread(new Runnable(){

			@Override
			public void run() {
				while(true){
					try {
						Thread.sleep(10);
					} catch (Exception e) {
						e.printStackTrace();
					}
					outputer.output("lihuoming");
				}
			}
			
		}).start();
	}
	class Outputer{
		public void output(String name){
			int len = name.length();
			for(int i = 0; i < len; i++){
				System.out.print(name.charAt(i));
			}
			System.out.println();
		}
	}
}



线程1和线程2在外部类的init方法中,同时开启了,两个线程夺取内部类的资源,于是会出现线程1夺取一半时,线程2过来夺取。而本意是想,线程1执行一个,线程2执行一个。
输出结果如下:
zhangxiaoxlihuoming
iang
lihuozhanming
gxiaoxiang
lihuoming
zhangxiaoxiang
lihuoming
zhangxiaoxiang
lihzhangxiaoxiang
uoming
lihuozhming


因此,出现了所谓的线程安全隐患。

保证原子性,需要给并发的代码块加锁。
不过下面的方式是错误的

	class Outputer{
		public void output(String name){
			synchronized (name) {
				int len = name.length();
				for(int i = 0; i < len; i++){
					System.out.print(name.charAt(i));
				}
				System.out.println();
			}			
		}
	}

synchronized里边的是一个栓子,应该是所有线程对象都用的是同一个栓子才可以达到互斥的效果。上面的写法,每个线程都有自己的传过来的不同的name,因此,起不到互斥效果。
输出效果如下:
ang
lihuoming
zhangxiaoxiang
lihuoming
zhangxiaoxiang
lizhangxiaoxiang
huoming
lihuomzhangxiaoxiang
ing


因此,实现互斥的锁,应该是每个线程都持有的一样的一把锁(这把锁必须是同一个对象的,如果每个线程都new了一个Outputer就不能实现互斥了,因为不是同一个对象),因此,可以在类中定义一个String s,那么每个在使用这个类时,使用的锁都是s锁,可以实现互斥的效果。
	class Outputer{
		String s = "xxx";
		public void output(String name){
			synchronized (s) {
				int len = name.length();
				for(int i = 0; i < len; i++){
					System.out.print(name.charAt(i));
				}
				System.out.println();
			}			
		}
	}


输出结果如下:
lihuoming
lihuoming
zhangxiaoxiang
lihuoming
zhangxiaoxiang
zhangxiaoxiang
lihuoming
zhangxiaoxiang
lihuoming
lihuoming
zhangxiaoxiang
zhangxiaoxiang


可以使用当前对象this作为锁,这样也可以实现互斥,因为他们都是来自同一个唯一的new出来的对象。
	class Outputer{
		
		public void output(String name){
			synchronized (this) {
				int len = name.length();
				for(int i = 0; i < len; i++){
					System.out.print(name.charAt(i));
				}
				System.out.println();
			}			
		}
	}


当两个线程分别调用下面两个方法的时候,也可以实现互斥的效果,因为这两个方法都是使用this作为锁。
		public void output(String name){
			synchronized (this) {
				int len = name.length();
				for(int i = 0; i < len; i++){
					System.out.print(name.charAt(i));
				}
				System.out.println();
			}			
		}
		
		public synchronized void output2(String name){ {
				int len = name.length();
				for(int i = 0; i < len; i++){
					System.out.print(name.charAt(i));
				}
				System.out.println();
			}			
		}

输出结果如下:
zhangxiaoxiang
lihuoming
zhangxiaoxiang
lihuoming
zhangxiaoxiang
lihuoming


静态时,不与锁关系,但是最好还是加
static class Outputer {

		public void output(String name) {
			synchronized (Outputer.class) {
				int len = name.length();
				for (int i = 0; i < len; i++) {
					System.out.print(name.charAt(i));
				}
				System.out.println();
			}
		}

		public synchronized void output2(String name) {
			{
				int len = name.length();
				for (int i = 0; i < len; i++) {
					System.out.print(name.charAt(i));
				}
				System.out.println();
			}
		}

		public static synchronized void output3(String name) {
			{
				int len = name.length();
				for (int i = 0; i < len; i++) {
					System.out.print(name.charAt(i));
				}
				System.out.println();
			}
		}
	}


分享到:
评论

相关推荐

    java操作系统多线程课程设计

    在Java编程语言中,操作系统多线程课程设计是一项重要的学习任务,它涉及到如何高效地利用计算机资源,特别是在并发环境中。本课程设计的核心是模拟仓库商店模型,通过创建多个线程来模拟实际的仓库、商店之间的商品...

    java 多线程的小游戏 Java 课程设计 Java毕业设计 多线程的小游戏 经典

    在这个课程设计或毕业设计项目中,学生通常会被要求实现一个能够展示多线程特性的游戏,比如经典的“猜数字”或者“抢红包”等,这些游戏都需要多个线程协作来完成。 首先,我们来看多线程的基本概念。在Java中,...

    C++多线程学习

    在C++编程中,多线程技术是一种强大的工具...理解并熟练运用这些概念和工具,能够帮助开发者编写出高效且安全的多线程应用程序。在实际学习过程中,深入探究这些知识点,结合实践案例,将会对提升C++编程技能大有裨益。

    java多线程下载课程设计工程源码

    Java多线程下载课程设计是一项常见且实用的项目,它涉及到计算机网络、操作系统以及Java编程语言的核心特性。在这个工程源码中,开发者可能利用了Java的并发能力来提高下载效率,实现了多线程同时下载文件的不同部分...

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

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

    java课程设计 多线程设计 内含源代码 打包发布

    Java课程设计中的多线程设计是一项重要的编程技能,它涉及到并发执行、资源共享、同步机制等多个核心概念。在Java中,多线程允许程序同时执行多个不同的任务,极大地提高了程序的效率和响应速度。本课程设计的重点是...

    解决多线程编程中的同步互斥问题

    使用关键段可以有效地解决多线程编程中的同步互斥问题,确保了在多线程环境中对共享资源的安全访问。但是需要注意的是,关键段仅能解决单个CPU核心上的互斥访问问题,对于多处理器或多核心环境下的同步问题可能需要...

    VC++简单的多线程聊天程序课程设计

    本课程设计项目旨在利用Visual C++(VC++)开发一个简单的多线程局域网聊天程序。随着互联网的发展,即时通讯软件如QQ、MSN等已经成为人们日常生活中的重要组成部分。这些软件的实现往往涉及到复杂的网络通信和多...

    多线程下载器 Java课程设计 Java 课程设计 Java毕业设计

    3. **并发控制**:在多线程环境中,必须确保线程安全,防止数据竞争和死锁。Java提供了`synchronized`关键字、`Lock`接口以及各种同步工具类(如`Semaphore`, `CyclicBarrier`)来实现并发控制,保证不同线程间的...

    多线程开发书籍

    - **《Java并发编程实战》**:本书详细介绍了Java平台下的多线程编程技术,包括线程安全、锁、并发集合等方面的内容。 - **《C++ Concurrency in Action》**:适合C++开发者,全面介绍了如何使用C++11/14标准库中的...

    20071010am--.NET Windows编程系列课程(15):多线程编程.pdf

    ### .NET Windows编程系列课程(15):多线程编程 #### 一、课程简介 本课程由邵志东讲师提供,旨在帮助学员深入了解.NET框架下的多线程编程技术。课程内容涵盖线程的基本概念、.NET环境下的多线程编程实践、线程池的...

    易语言 单线程 改多线程 项目实战 教程.zip

    "易语言 单线程改多线程 项目实战教程"是一门专门针对易语言编程环境设计的课程,旨在帮助开发者了解如何将原本的单线程程序转换为多线程程序,以充分利用现代计算机的多核处理器资源。易语言作为一款面向中文用户的...

    线程安全型栈

    实现线程安全型栈的主要目的在于解决多线程环境下的资源竞争问题。通过对栈的操作加上互斥机制,可以确保多个线程同时访问栈时不会出现错误。同时,线程安全型栈还能够提高多线程环境下的系统性能和可靠性。 为了...

    基于多线程的端口扫描程序课程设计报告.doc

    通过这个课程设计,学生不仅能掌握Java网络编程和多线程的基础知识,还能实际应用这些技术解决实际问题,提升其在未来工作中处理类似任务的能力。此外,课程设计报告的编写也是对学生书面表达能力和技术文档编制能力...

    操作系统线程通信课程设计

    这限制了多线程环境下任务的并发执行,现代操作系统已经克服了这一问题。 5. **线程的创建与撤销**:创建线程通常涉及为新线程分配资源(如栈空间)并初始化TCB。撤销线程时,需要清理其占用的资源,避免资源泄露。...

    多线程Web服务器的设计与实现

    5. **并发控制**:在多线程环境中,必须考虑线程安全问题,比如资源竞争和死锁。Java提供了一些并发工具类,如`synchronized`关键字、`ReentrantLock`、`Semaphore`等,用于管理和控制并发访问,确保数据一致性。 6...

    操作系统课程设计多线程 生产者消费者问题

    综上所述,这个"操作系统课程设计多线程 生产者消费者问题"项目将涵盖Java多线程编程、并发控制、线程安全的数据结构和通信机制等多个重要知识点,对理解并发编程有极大的实践价值。在实际操作中,需要综合运用这些...

    多线程高新(黑马程序员)

    然而,多线程也存在一些挑战和问题,如线程安全、竞态条件、死锁等。线程安全是指在多线程环境下,数据访问的正确性不受影响。为了确保线程安全,开发者需要使用同步机制,如Java的`synchronized`关键字、锁、信号量...

    操作系统课程设计——简单多线程

    在本项目"操作系统课程设计——简单多线程"中,我们将深入探讨多线程这一关键概念,以及它在操作系统中的实现。 多线程是指在一个进程中同时执行多个线程,每个线程都具有独立的执行路径,可以并行处理任务,提高...

    多线程和套接字编程程序

    3. 共享资源:学习如何在多线程环境中安全地共享数据。 4. 线程通信:线程间的协作,如使用`std::future`和`std::promise`进行异步通信。 5. 线程局部存储:使用`std::thread_local`关键字为每个线程创建局部变量。 ...

Global site tag (gtag.js) - Google Analytics