`

传统线程互斥技术

 
阅读更多
2个线程在同一个实例的方法中输出
会出现如下结果:
zhangxiaoxiang
zhangxiaoxiang
lihuoming
zhangxiaoxiang
lihuomizhangxiaoxiang
ng
zhangxiaoxiang
lihuoming
zhangxiaoxiang
如下代码可以产生错误的结果:
1、2个线程同时访问,output方法一个线程没有允许完成另一个线程就进来。
  
package cn.itcast.heima2;

public class TraditionalTreadSynchrorized {

	public static void main(String[] args) {
		new TraditionalTreadSynchrorized().init();
	}

	public void init() {
		final Outputer output = new Outputer();
		new Thread(new Runnable() {
			@Override
			public void run() {
				while (true) {
					try {
						Thread.sleep(10);
					} catch (InterruptedException e) {
						e.printStackTrace();
					}
					output.output("zhangxiaoxiang");
				}
			}
		}).start();

		new Thread(new Runnable() {

			@Override
			public void run() {
				while (true) {
					try {
						Thread.sleep(10);
					} catch (InterruptedException e) {
						e.printStackTrace();
					}
					output.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();
		}

	}
}
 
 

 正确代码: 

使用对象锁机制将输出体进行锁定

synchronized (this) { }

package cn.itcast.heima2;

public class TraditionalTreadSynchrorized {

	public static void main(String[] args) {
		new TraditionalTreadSynchrorized().init();
	}

	public void init() {
		final Outputer output = new Outputer();
		new Thread(new Runnable() {
			@Override
			public void run() {
				while (true) {
					try {
						Thread.sleep(10);
					} catch (InterruptedException e) {
						e.printStackTrace();
					}
					output.output("zhangxiaoxiang");
				}
			}
		}).start();

		new Thread(new Runnable() {

			@Override
			public void run() {
				while (true) {
					try {
						Thread.sleep(10);
					} catch (InterruptedException e) {
						e.printStackTrace();
					}
					output.output("lihuoming");
				}
			}
		}).start();
	}

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

	}
}

 

 

 

 

  2、错误代码

  虽然两个线程调用的方法不同,可是还是在同一个对象中,当一个线程没有输出完毕的时候第二个线程就打印了

system.out.println();进行换行。

 

package cn.itcast.heima2;

public class TraditionalTreadSynchrorized {

	public static void main(String[] args) {
		new TraditionalTreadSynchrorized().init();
	}

	public void init() {
		final Outputer output = new Outputer();
		new Thread(new Runnable() {
			@Override
			public void run() {
				while (true) {
					try {
						Thread.sleep(10);
					} catch (InterruptedException e) {
						e.printStackTrace();
					}
					output.output("zhangxiaoxiang");
				}
			}
		}).start();

		new Thread(new Runnable() {

			@Override
			public void run() {
				while (true) {
					try {
						Thread.sleep(10);
					} catch (InterruptedException e) {
						e.printStackTrace();
					}
					output.output2("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();
		}
		public void output2(String name) {
			int len = name.length();
				for (int i = 0; i < len; i++) {
					System.out.print(name.charAt(i));
				}
				System.out.println();
		}

	}
}

 

 

正确代码:

synchronized 关键字加在方法上默认锁定this 对象 如果在方法中需要 使用synchronized(this){}

package cn.itcast.heima2;

public class TraditionalTreadSynchrorized {

	public static void main(String[] args) {
		new TraditionalTreadSynchrorized().init();
	}

	public void init() {
		final Outputer output = new Outputer();
		new Thread(new Runnable() {
			@Override
			public void run() {
				while (true) {
					try {
						Thread.sleep(10);
					} catch (InterruptedException e) {
						e.printStackTrace();
					}
					output.output("zhangxiaoxiang");
				}
			}
		}).start();

		new Thread(new Runnable() {

			@Override
			public void run() {
				while (true) {
					try {
						Thread.sleep(10);
					} catch (InterruptedException e) {
						e.printStackTrace();
					}
					output.output2("lihuoming");
				}
			}
		}).start();
	}

	static 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();
			}
		}
		
		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();
		}
		
			}
}

 

 

错误代码:

因为一个线程调用的静态方法,即两个线程不是调用的同一个对象,也就说明synchronized不是锁定的同一个对象。

package cn.itcast.heima2;

public class TraditionalTreadSynchrorized {

	public static void main(String[] args) {
		new TraditionalTreadSynchrorized().init();
	}

	public void init() {
		final Outputer output = new Outputer();
		new Thread(new Runnable() {
			@Override
			public void run() {
				while (true) {
					try {
						Thread.sleep(10);
					} catch (InterruptedException e) {
						e.printStackTrace();
					}
					output.output("zhangxiaoxiang");
				}
			}
		}).start();

		new Thread(new Runnable() {

			@Override
			public void run() {
				while (true) {
					try {
						Thread.sleep(10);
					} catch (InterruptedException e) {
						e.printStackTrace();
					}
					Outputer.output3("lihuoming");
				}
			}
		}).start();
	}

	static 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();
			}
		}
		
		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();
		}

	}
}

 

 正确代码如下:

因为需要锁定静态对象 所以要使用Outputer.class

package cn.itcast.heima2;

public class TraditionalTreadSynchrorized {

	public static void main(String[] args) {
		new TraditionalTreadSynchrorized().init();
	}

	public void init() {
		final Outputer output = new Outputer();
		new Thread(new Runnable() {
			@Override
			public void run() {
				while (true) {
					try {
						Thread.sleep(10);
					} catch (InterruptedException e) {
						e.printStackTrace();
					}
					output.output("zhangxiaoxiang");
				}
			}
		}).start();

		new Thread(new Runnable() {

			@Override
			public void run() {
				while (true) {
					try {
						Thread.sleep(10);
					} catch (InterruptedException e) {
						e.printStackTrace();
					}
					Outputer.output3("lihuoming");
				}
			}
		}).start();
	}

	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 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多线程与并发库高级应用视频教程22集

    资源名称:Java多线程与并发库高级应用视频教程22集资源目录:【】01传统线程技术回顾【】02传统定时器技术回顾【】03传统线程互斥技术【】04传统线程同步通信技术【】04传统线程同步通信技术_分割纪录【】05线程...

    多线程的小例子,线程互斥的问题

    本文将深入探讨标题和描述中提到的“多线程的小例子”以及线程互斥的概念。 线程互斥是多线程编程中的一个关键概念,用于确保在特定时间内,只有一个线程可以访问共享资源,以防止数据不一致性和竞态条件。在C#中,...

    传智播客_张孝祥_传统线程同步通信技术

    张孝祥老师的课程"传智播客_张孝祥_传统线程同步通信技术"深入浅出地讲解了这一主题,旨在帮助开发者理解和掌握线程间的协作与数据共享方式。 线程同步是指在多线程环境下,控制多个线程按一定的顺序执行,以避免...

    多线程的讲解

    ### 三、传统线程互斥技术 #### 3.1 互斥问题 在多线程环境中,多个线程可能同时访问共享资源(如银行账户余额),如果没有适当的控制措施,可能导致数据一致性问题或竞态条件。这种情况下,需要采取措施确保同一...

    C#.NET多线程实例6个(包括多线程基本使用,多线程互斥等全部多线程使用实例)(0515).rar

    这个压缩包“C#.NET多线程实例6个(包括多线程基本使用,多线程互斥等全部多线程使用实例)(0515).rar”包含了六个关于C#中多线程应用的实例,涵盖了从基础到高级的多线程使用场景,如线程创建、线程同步和互斥。...

    C#.NET多线程实例6个(包括多线程基本使用,多线程互斥等全部多线程使用实例)_0520.rar

    在.NET框架中,C#语言提供了强大的多线程支持,使得开发者可以充分利用现代多核处理器的优势,实现并行处理和优化...学习并理解这些实例,将有助于开发者更好地在C#.NET项目中运用多线程技术,提高程序的性能和效率。

    传统线程同步通信技术二

    了解并熟练掌握这些传统线程同步通信技术,能帮助你在多线程编程中有效地避免数据竞争,提高程序的并发性和可靠性。在实际开发中,应根据具体需求选择最合适的同步机制,同时考虑线程同步带来的开销,以实现最佳性能...

    传统线程同步通信技术一

    本文将深入探讨传统线程同步通信技术,主要包括临界区、信号量、互斥量以及事件对象。 1. **临界区**(Critical Section) 临界区是程序中用于访问共享资源的代码段。为了防止多个线程同时进入临界区,我们可以...

    java加强笔记

    传统线程互斥技术 - 线程间的互斥通常通过`synchronized`关键字或显式锁(`Lock`)来实现。 ##### 4. 传统线程同步通信技术 - 线程之间的同步通信可以通过`wait()`、`notify()`和`notifyAll()`等方法来实现。 #####...

    C++ 多线程综合技术篇

    在C++编程中,多线程技术是一种关键的并发处理机制,它允许程序同时执行多个独立的任务,从而提高系统的效率和响应性。本综合技术篇将深入探讨C++中的多线程概念、实现方法以及常见问题。 一、线程基础 线程是操作...

    linux线程技术

    【Linux线程技术】在操作系统领域,Linux线程是指在Linux环境下实现的多线程编程技术。虽然在早期的Linux内核中并没有直接支持线程的概念,而是通过轻量级进程(Lightweight Process, LWP)来模拟线程的行为。在...

    Visual_C++利用互斥量同步线程实现文件读取进度条

    为了更高效地管理文件读取与进度更新过程,本篇文章将介绍如何利用线程同步技术中的互斥量(mutex)来实现这一功能。 #### 二、线程与进程基础知识 - **进程**:一个正在执行的应用程序及其资源集合,包括私有的虚拟...

    Delphi多线程详解_delphi_delphi多线程_多线程_

    除了传统的多线程,Delphi还支持异步编程模型,如使用IO Completion Ports(IOCP)来处理I/O密集型任务,提高系统吞吐量。IOCP允许系统在I/O操作完成时自动通知线程,避免了不必要的等待和上下文切换。 七、实际...

    java多线程编程技术

    Java多线程编程技术是Java编程语言中一个非常重要的技术分支,它允许程序员在程序中创建多个执行流(线程),这些线程可以并发执行,从而使得程序能更加高效地利用系统资源,同时提高应用的响应速度和吞吐能力。...

    Linux下多线程技术分析及应用.pdf

    Linux下的多线程不同于传统的进程创建,它通过克隆(`clone`)系统调用来创建线程,这种方法显著降低了CPU开销和内存消耗。克隆出的线程与父进程共享资源,例如文件、信号处理程序和虚拟内存,同时利用“写时复制”...

    基于消息的异步套接字和多线程技术网络通信编程

    传统的同步套接字会在执行I/O操作时阻塞当前线程,直到操作完成,这可能会严重影响程序的响应速度。相比之下,异步套接字则能在数据到达时通过特定机制通知程序,从而使程序无需等待即可继续执行其他任务。 - **...

    Linux系统的线程技术.pdf

    用户级线程完全由用户空间的程序实现和管理,包括线程调度、同步和互斥,这提供了更高的灵活性,适用于特定的应用场景,如实时处理、数据下载和采集。另一方面,内核级线程则由操作系统内核管理,通过系统调用来实现...

Global site tag (gtag.js) - Google Analytics