`
xiaozhouzhou
  • 浏览: 13939 次
  • 性别: Icon_minigender_1
社区版块
存档分类
最新评论

多线程初谈——线程的创建与互斥问题

 
阅读更多
多线程初谈——线程的创建与互斥
     对于线程起初也很是不解,觉得很乱,线程的互斥就跟别提了。创建线程也一直只能通过创建Thread子类的方法,像那个实例化Runnable对象一直不是很理解,也没敢用,二者的线程创建区别在哪也不清楚。带着这些困惑一直到了现在。随着对Android语言的深入学习,发现线程真的很重要,不弄清楚就难以做出一个好的产品,不解决线程的互斥,同步通信,死锁问题,就无法得到一个高质量,高安全的东西。所以趁着国庆期间把线程同步这一块重新学习了一遍。以下是我在学习过程中做出的一些总结,希望对还在苦恼的你有些许帮助。一、创建线程的两种方法:
1、通过创建Thread子类来实现线程:创建Thread子类,子类中重写run方法覆盖掉父类的run方法。
2、实例化Runnable对象来实现线程:给Thread类的构造函数传一个Runnable对象,再调用Runnable对象中的run方法。(Runnable对象不是线程,是线程要运行的代码的宿主)

如果对于第二种方法不是很理解,对于为什么要实例化Thread类,再加入对象Runnable有疑问.像代码:
Thread thread=new Thread(new Runnable(){
			@Override
			public void run() {
				// TODO Auto-generated method stub
			}
		});

下面给出一段源代码,我想你这时就知道为什么是这样了。
public Thread(Runnable target) {
        init(null, target, "Thread-" + nextThreadNum(), 0);
    }
public void run() {
        if (target != null) {
            target.run();
        }
    }

由此可见,实例化Runnable接口来创建线程的实质就是,把run方法封装入Runnable对象,再通过Thread的构造方法将Runnable对象传入

二、两种方法的些许不同:
第二种方法更趋向于面向对象。我们在编码的过程中是面向对象的,第二种方法,是把run方法封装到一个独立对象Runnable中去,然后放入线程对象Thread中.当然在创建线程时,两种方法都是可以的。
下面给出一段线程创建代码,以供参考

public static void main(String args[]){
		/*
		 * 通过创建Thread子类的的构造线程的方法
		 */
		Thread thread=new Thread(){
			//重写父类的run方法
			public void run(){
				while(true){
					try {
						//线程休眠0.5秒
						Thread.sleep(500);
					} catch (Exception e) {
						e.printStackTrace();
					}
					//打印当前线程名
					System.out.println(Thread.currentThread().getName());
				}
			}
		};
		thread.start();//线程启动
		
		/*
		 * 实例化Runnable对象,传入Thread类中来创建线程
		 */
		Thread thread2=new Thread(new Runnable(){

			
			public void run() {
				while(true){
					try {
						//线程休眠0.5秒
						Thread.sleep(500);
					} catch (Exception e) {
						e.printStackTrace();
					}
					//打印当前线程名
					System.out.println(Thread.currentThread().getName());
				}
			}
		});
		thread2.start();//线程启动
		

		
	}

其运行结果


如果你觉得对两者的创建及些许的区别有很好的了解,那就思考下,下面的代码会输出什么样的结果:
//创建Thrad子类
new Thread(new Runnable(){//创建Runnable对象,传入Thread中
	public void run() {
		while(true){
			try {
				//线程休眠0.5秒
				Thread.sleep(500);
			} catch (Exception e) {
				e.printStackTrace();
			}
			//打印当前线程名
			System.out.println("runnable:"+Thread.currentThread().getName());
		}
	}
	
}){
	public void run() {
		while(true){
			try {
				//线程休眠0.5秒
				Thread.sleep(500);
			} catch (Exception e) {
				e.printStackTrace();
			}
			//打印当前线程名
			System.out.println("thread:"+Thread.currentThread().getName());
		}
	}
}.start();//开启线程
运行结果:


--------------------------------分割线-------------------------------
三、线程的互斥问题。
线程的互斥就是一个关键字:synchornized.互斥锁定的必须是同一个对象,必须是同一个锁。
我们在用到多线程操作同一份数据时,就会用上线程的互斥,如果这块不懂的话,代码会出现很严重的逻辑问题和产品安全性问题。就如银行的存取款,如果我原有1000元存款,现在父母往里面又存了500元,同时我在取钱200,如果银行系统线程同步没处理好,那么就很可能出现自己的存款总后只有800元,而不是1300.
下面给出没有加线程互斥的代码:
public class SteupThread {
	
	public static void main(String args[]){
		new SteupThread().init();
	}
	public void init(){
	//内部类不能访问局部变量,为了访问局部变量,需加final
	final Output output=new Output();
		//线程1
		new Thread(new Runnable(){
			public void run() {
				while(true){
					try {
						Thread.sleep(500);
					} catch (InterruptedException e) {
						e.printStackTrace();
					}
					output.print1("wobeidayinle");
				}
			}
			
		} ).start();
		
		//线程2
		new Thread(new Runnable(){
			public void run() {
				while(true){
					try {
						Thread.sleep(500);
					} catch (InterruptedException e) {
						e.printStackTrace();
					}
					output.print2("howareyou");
				}
			}
			
		} ).start();
	}
	//内部类
	class Output{
		public void print1(String st){
			int len=st.length();
			for(int i=0;i<len;i++){
				System.out.print(st.charAt(i));
			}
			System.out.println();
		}
		public void print2(String st){
			int len=st.length();
			for(int i=0;i<len;i++){
				System.out.print(st.charAt(i));
			}
			System.out.println();
		}
	}
}

运行结果


通过上面的代码可以知道:在打印语句:howareyou时被打断了,为了避免此类事情发生,就必须用到线程的互斥了。
代码改进如下:
将内部类Output中的同步方法用synchornized锁定
//内部类
	class Output{
		public synchronized void print1(String st){
			int len=st.length();
			for(int i=0;i<len;i++){
				System.out.print(st.charAt(i));
			}
			System.out.println();
		}
		public synchronized void print2(String st){
			int len=st.length();
			for(int i=0;i<len;i++){
				System.out.print(st.charAt(i));
			}
			System.out.println();
		}
	}


线程的创建与互斥就总结到此,如果觉得这些简单,认为学懂了线程的互斥,就思考一下这个问题怎么解决吧:
问:子线程循环10次,接着主线程循环100次,接着又子线程循环10次,然后又主线程循环100次,如此循环50次,请写出相应程序。(此为一次公司招聘面试题!如果没有解决,后面会给出代码,此类为线程同步通信问题。)
  • 大小: 12.1 KB
  • 大小: 13.3 KB
  • 大小: 12.9 KB
1
3
分享到:
评论

相关推荐

    操作系统实验——进程的同步与互斥(读者写者问题)

    以生产者消费者模型为基础,在Windows环境下创建一个控制台进程,在该进程中创建读者写者线程模拟生产者和消费者。写者线程写入数据,然后将数据放置在一个空缓冲区中供读者线程读取。读者线程从缓冲区中获得数据,...

    操作形同实验——进程同步和互斥

    操作形同实验——进程同步和互斥 (1) 通过编写程序实现进程同步和...(2) 了解Windows2000/XP中多线程的并发执行机制,线程间的同步和互斥。 (3) 学习使用Windows2000/XP中基本的同步对象,掌握相应的API函数。

    多线程的奥秘——充分认识多线程

    多线程是现代计算机编程中的一个重要概念,尤其在操作系统如Windows这样的多任务环境中,多线程使得程序能够并发执行多个任务,从而充分利用系统的计算资源,提高程序的响应速度和效率。在C#编程中,多线程机制是...

    多线程编程教程——作者:韩耀旭

    #### 一、多线程问题提出 在软件开发过程中,经常会遇到一些耗时较长的任务,例如网络请求、文件读写等。这些任务如果在一个单线程环境下运行,很容易导致整个应用程序在执行这些任务期间变得无响应,即所谓的...

    线程学习资料——平台VC6

    "MutiTread"这个文件可能包含了关于使用互斥量实现同步的具体示例代码或教程,可以帮助学习者深入理解如何在VC++ 6.0环境中创建和管理线程,以及如何利用互斥量解决多线程同步问题。通过实践这些示例,学习者可以更...

    操作系统实验 多线程同步与互斥 java编写 有界面

    在“操作系统实验 多线程同步与互斥 java编写 有界面”的实验中,可能需要设计一个图形用户界面(GUI),通过按钮或事件触发线程的创建和同步操作,直观地展示线程间的交互和同步效果。例如,可以模拟银行账户转账,...

    多线程libmpeg2——源代码

    3. **同步与通信**:在多线程环境下,线程间的同步和通信是非常关键的。例如,使用互斥锁(mutex)防止多个线程同时访问同一数据,条件变量(condition variable)用于线程间的协调,信号量(semaphore)控制资源的...

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

    本教程将深入讲解Java线程的相关知识,包括进程与线程的基本概念、线程的创建和启动、多线程的互斥与同步、线程状态和线程控制以及死锁的概念。 首先,我们要理解进程与线程的区别。进程是操作系统资源分配的基本...

    多线程编程——MFC中的多线程开发

    值得注意的是,多线程编程会引入竞态条件、死锁和资源争抢等问题,因此需要特别注意线程安全。在访问共享资源时,应使用互斥量或者临界区(CCriticalSection)进行保护,避免数据不一致。 此外,MFC还提供了一些...

    多线程编程——线程的同步

    在“多线程编程之四——线程的同步”这个文件中,可能包含了上述各种同步机制的具体实现示例和详细说明,这对于初学者来说是一份非常宝贵的参考资料。通过学习和理解这些例子,开发者可以更好地掌握如何在实际项目中...

    多线程编程——互斥锁使用(Jack_pthread_mutex_test.rar)

    多线程编程:互斥锁使用。 打包文件包含两个文件:c文件源代码、Makefile文件,运行环境在Ubuntu14.04下,使用自带的gcc编译器,同学们只需将文件夹复制到某一目录下之后在终端执行:1.“make”生成“test”可执行...

    多线程编程——实战篇

    接下来我们将通过一个具体的例子——“厨师-食客”模式来深入理解多线程编程的实际应用。 1. **模型介绍**: - 生产者(厨师):负责制作食物,并将其放入共享的“仓库”(桌子)。 - 消费者(食客):从“仓库”...

    Visual C++高级编程技术——MFC与多线程篇.rar

    本教程“Visual C++高级编程技术——MFC与多线程篇”将深入探讨这两个关键概念。 MFC是C++面向对象编程的一个重要框架,它基于Windows API,将复杂的Win32 API函数封装为易于理解和使用的类。MFC包含了一系列的类,...

    c++多线程同步——信号量

    在C++编程中,多线程同步是一种关键的技术,它允许多个执行线程协同工作,以避免数据竞争和死锁等并发问题。信号量(Semaphore)是实现多线程同步的一种有效工具,常用于控制对共享资源的访问。在这个名为"Mthread11...

    操作系统实验报告——进程同步与互斥.doc

    操作系统实验报告——进程同步与互斥 本实验报告的主要目的是掌握基本的进程同步与互斥算法,理解生产者-消费者问题,并学习使用 Windows 2000/XP 中基本的同步对象,掌握相关 API 的使用方法。 一、进程同步与...

    操作系统实验报告——进程同步与互斥.pdf

    操作系统实验报告——进程同步与互斥 该实验报告的目的旨在掌握基本的进程同步与互斥算法,理解生产者-消费者问题,并学习使用 Windows 2000/XP 中基本的同步对象,掌握相关API 的使用方法。实验环境采用 Windows ...

Global site tag (gtag.js) - Google Analytics