- 浏览: 13359 次
- 性别:
最新评论
多线程初谈——线程的创建与互斥
对于线程起初也很是不解,觉得很乱,线程的互斥就跟别提了。创建线程也一直只能通过创建Thread子类的方法,像那个实例化Runnable对象一直不是很理解,也没敢用,二者的线程创建区别在哪也不清楚。带着这些困惑一直到了现在。随着对Android语言的深入学习,发现线程真的很重要,不弄清楚就难以做出一个好的产品,不解决线程的互斥,同步通信,死锁问题,就无法得到一个高质量,高安全的东西。所以趁着国庆期间把线程同步这一块重新学习了一遍。以下是我在学习过程中做出的一些总结,希望对还在苦恼的你有些许帮助。一、创建线程的两种方法:
1、通过创建Thread子类来实现线程:创建Thread子类,子类中重写run方法覆盖掉父类的run方法。
2、实例化Runnable对象来实现线程:给Thread类的构造函数传一个Runnable对象,再调用Runnable对象中的run方法。(Runnable对象不是线程,是线程要运行的代码的宿主)
如果对于第二种方法不是很理解,对于为什么要实例化Thread类,再加入对象Runnable有疑问.像代码:
下面给出一段源代码,我想你这时就知道为什么是这样了。
由此可见,实例化Runnable接口来创建线程的实质就是,把run方法封装入Runnable对象,再通过Thread的构造方法将Runnable对象传入。
二、两种方法的些许不同:
第二种方法更趋向于面向对象。我们在编码的过程中是面向对象的,第二种方法,是把run方法封装到一个独立对象Runnable中去,然后放入线程对象Thread中.当然在创建线程时,两种方法都是可以的。
下面给出一段线程创建代码,以供参考。
其运行结果:
如果你觉得对两者的创建及些许的区别有很好的了解,那就思考下,下面的代码会输出什么样的结果:
--------------------------------分割线-------------------------------
三、线程的互斥问题。
线程的互斥就是一个关键字:synchornized.互斥锁定的必须是同一个对象,必须是同一个锁。
我们在用到多线程操作同一份数据时,就会用上线程的互斥,如果这块不懂的话,代码会出现很严重的逻辑问题和产品安全性问题。就如银行的存取款,如果我原有1000元存款,现在父母往里面又存了500元,同时我在取钱200,如果银行系统线程同步没处理好,那么就很可能出现自己的存款总后只有800元,而不是1300.
下面给出没有加线程互斥的代码:
运行结果:
通过上面的代码可以知道:在打印语句:howareyou时被打断了,为了避免此类事情发生,就必须用到线程的互斥了。
代码改进如下:
将内部类Output中的同步方法用synchornized锁定。
线程的创建与互斥就总结到此,如果觉得这些简单,认为学懂了线程的互斥,就思考一下这个问题怎么解决吧:
问:子线程循环10次,接着主线程循环100次,接着又子线程循环10次,然后又主线程循环100次,如此循环50次,请写出相应程序。(此为一次公司招聘面试题!如果没有解决,后面会给出代码,此类为线程同步通信问题。)
对于线程起初也很是不解,觉得很乱,线程的互斥就跟别提了。创建线程也一直只能通过创建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次,请写出相应程序。(此为一次公司招聘面试题!如果没有解决,后面会给出代码,此类为线程同步通信问题。)
发表评论
-
线程的同步通信与线程范围内的数据共享问题
2013-10-02 22:05 1324线程的同步通信与线程范围内的数据共享问题一、线程的同步通信 什 ... -
网络通信见解之谈
2013-07-17 13:38 616一、网络通信的基本原理 现如今,出现了各式各样的聊天平 ... -
简单的bmp文件打开与保存
2013-07-01 22:24 881简单的bmp文件打开与保 ... -
分形浅谈——科赫曲线和L-System
2013-06-24 22:47 1233分形浅谈开始接触到分行图时,感觉很难,无法下手,只能做出第一层 ... -
对关键字final、static的理解
2013-05-10 23:36 534一、final关键字 fin ... -
对关键字的理解——访问权限
2013-05-10 16:17 598关键字public、pr ... -
队列的定义及运用
2013-03-23 14:58 640队列简称队,是限制在表的一端进行插入操作,而在表的另一端进行删 ... -
重绘方法的重写利用
2013-03-22 21:44 617重绘是为了在画布上保留原始痕迹的一种方法,他的目的是用来保存你 ... -
数组的定义及递归的运用
2013-03-22 21:43 1020一、数组有一维数组、 ... -
监听器与变量的作用域
2013-03-22 21:41 703监听器是用来实现一些可控操作的工具,如你在打开一个QQ界面的时 ... -
java中的继承
2013-03-08 00:31 566Java中的接口 什么是接口?不是以class定义的类而是以i ... -
Java中类的继承、重写、自动转型以及多态
2013-03-06 01:13 716Java中类的继承、重写、自动转型以及多态 1) 类的继承 在 ... -
java的构造器方法、方法重载和引用传递
2013-03-04 23:55 729Java的构造器方法、方法重载与引用传递 一、 构造器方法 构 ... -
JAVA语言中的类与对象
2013-03-04 00:08 731Java语 ...
相关推荐
以生产者消费者模型为基础,在Windows环境下创建一个控制台进程,在该进程中创建读者写者线程模拟生产者和消费者。写者线程写入数据,然后将数据放置在一个空缓冲区中供读者线程读取。读者线程从缓冲区中获得数据,...
操作形同实验——进程同步和互斥 (1) 通过编写程序实现进程同步和...(2) 了解Windows2000/XP中多线程的并发执行机制,线程间的同步和互斥。 (3) 学习使用Windows2000/XP中基本的同步对象,掌握相应的API函数。
多线程编程:互斥锁使用。 打包文件包含两个文件:c文件源代码、Makefile文件,运行环境在Ubuntu14.04下,使用自带的gcc编译器,同学们只需将文件夹复制到某一目录下之后在终端执行:1.“make”生成“test”可执行...
在《秒杀多线程系列》的前十五篇中介绍多线程的相关概念,多线程同步互斥问题《秒杀多线程第四篇一个经典的多线程同步问题》及解决多线程同步互斥的常用方法——关键段、事件、互斥量、信号量、读写锁。为了让大家...
单线程程序 多线程程序 Thread类的run方法和start方法 线程的启动 线程的启动(1)——利用Thread类的子类 线程的启动(2)——利用Runnable接口 线程的暂时停止 线程的共享互斥 synchronized方法 synchronized阻挡 ...
POSIX 线程库Pthreads介绍 POSIX pthreads库提供的基本线程的操作 线程的属性 线程互斥和同步 使用GDB 调试线程以及线程的调优 多线程网络服务器模型 试验题目
实例269——使用多线程进行文件搜索 实例270——获取当前系统的所有进程 实例271——实现应用程序在系统中只能运行一个实例 实例272——获取所有打开窗口程序的句柄、类名及标题 实例273——创建和终止进程 ...
摘要:Java源码,系统相关,线程同步,线程互斥 Java线程间同步互斥,在实际的编程中,经常要处理线程间的同步互斥问题。Java 语言内在强大的多线程支持使得处理这类问题变得相对来说比较简单。本例将模仿经典的线程...
摘要:VC/C++源码,系统相关,多线程同步 多线程十大经典案例之一秒杀多线程,多线程同步互斥问题《秒杀多线程第四篇一个经典的多线程同步问题》及解决多线程同步互斥的常用方法——关键段、事件、互斥量、信号量、...
线程安全问题的产生是因为多个线程并发访问共享数据造成的,如果能将多个线程对共享数据的并发访问改为串行访问,即一个共享数据同一时刻只能被一个线程访问,就可以避免线程安全问题。锁正是基于这种思路实现的一种...
掌握线程创建和终止的方法,加深对线程和进程概念的理解,会用同步与互斥方法实现线程之间的进行操作。 在学习操作系统课程的基础上,通过实践加深对进程同步的认识,同时,可以提高运用操作系统知识解决实际问题的...
在Linux环境下实现一个多线程对临界资源的互斥操作,利用信号量实现对临界资源的保护,支持Linux下文件输入输出,提高对Linux环境下多进程、多线程、信号量机制和文件操作等知识的理解。 设有进程A、B、C,分别调用...
4.1.3 多线程串口的应用 78 4.2 线程的操作 78 4.2.1 创建线程 78 4.2.2 终止线程 80 4.2.3 关于内存泄漏 81 4.3 线程间通信 81 4.3.1 使用全局变量 81 4.3.2 使用自定义消息 81 4.4 线程同步 82 4.4.1 使用临界区...
1.2 Linux的线程——轻量级进程 15 1.3 进程的创建——do_fork()函数详解 19 1.4 执行进程间切换 33 1.4.1 进程切换之前的工作 33 1.4.2 进程切换实务 —— switch_to宏 37 1.4.3 __switch_to函数 39 1.5 fork与...
├─Windows多线程编程技术与实例 ... ... ├─多线程,多接收模式串口类 ├─多线程文件传输 ├─多线程的日志记录DLL ├─多线程端口扫描程序 ├─多线程,多接收模式串口类 ├─实例10-多线程实例 ├─实例12-多...
Windows下解决经典的银行柜员服务问题,使用PV原语实现线程间同步和互斥,C++代码,下载后可直接运行
Parallel的使用 多线程系列(5)5天不再惧怕多线程——第五天 线程池 5天不再惧怕多线程——第四天 信号量 5天不再惧怕多线程——第三天 互斥体 5天不再惧怕多线程——第二天 锁机制 5天不再惧怕多线程——第一天 尝试...
第12讲 多线程的互斥(一) 第13讲 多线程的互斥(二) 第14讲 多线程的互斥(三) 数据库应用程序开发 第15讲 显示数据库信息 第16讲 数据库导航 第17讲 参数化查询 第18讲 主从数据库显示 第19讲 读取XML文件 ...
├─第53讲 文件系统监视器 │ └─第55讲 聊天室扩展之三——使用MS Agent <br>└ C#源代码第三部分多线程 ├─1-多线程 ├─2-多线程 ├─3-多线程互斥 ├─4-多线程互斥 ├─5-多线程...