多线程基础

线程是一个程序内部的顺序控制流。


线程和进程的区别:
  每个进程都有独立的代码和数据空间(进程上下文),进程间的切换会有较大的开销。
  线程可以看成是轻量级的进程,同一类线程共享代码和数据空间,每个线程有独立的运行栈和程序计数器(PC),线程切换的开销小。
  多进程:在操作系统中能同时运行多个任务(程序)
  多线程:在同一应用程序中有多个顺序流同时执行

 

当多线程sleep时,如何停止呢?
1、interrupt()方法,这个方法很粗暴不建议使用,这个相当于睡觉的时候一盆凉水泼下来,会抛出interruptedException。
2、stop()方法,已经废弃了,这个比interrupt更粗暴,直接停止线程。不建议使用。
3、用标量在外部控制。

join方法:合并某个线程。把处于并行运行状态的线程合并到当前线程中。

yield()方法:让出CPU,给其他线程执行的机会。

setPriority():设置优先级,优先级越高,cpu分得时间片就越多,越容易得到执行。

线程同步:在Java语言中,引入了对象互斥锁的概念,保证共享数据操作的完整性。每个对象都对应于一个可称为“互斥锁”的标记。这个标记保证在任何一个时刻,只能有一个线程访问该对象。
关键字synchronized来与对象的互斥锁联系。当某个对象synchronized修饰时,表明该对象在任一时刻只能由一个线程访问。synchronized可以作为关键字设在方法上,也可以使用synchronized(this){}中表明锁定该对象的内容。

尽量只锁定一个对象,避免死锁。

当一个线程锁定了一个方法的时候,其他线程可以通过其他方法修改值,所以,一定要保证所有有关这个变量的方法都要加锁。

同步实例:

[html] view plain copy

 print?

  1. <span style="font-family:Microsoft YaHei;"><span style="font-size:12px;">package thread;  
  2.   
  3. public class TT implements Runnable{  
  4.   
  5.     int b = 100 ;  
  6.       
  7.     @Override  
  8.     public void run() {  
  9.         m1() ;  
  10.     }  
  11.       
  12.     //只会锁定m1方法内的内容,不会锁定b  
  13.     public synchronized void m1() {  
  14.         b = 1000 ;  
  15.         try {  
  16.             Thread.sleep(5000);  
  17.         } catch (InterruptedException e) {  
  18.             e.printStackTrace();  
  19.         }  
  20.         System.out.println("b = " + b);  
  21.     }  
  22.   
  23.     public void m2() {  
  24.         System.out.println(b);  
  25.     }  
  26.       
  27.     public static void main(String[] args) {  
  28.         TT t = new TT() ;  
  29.         Thread thread = new Thread(t) ;  
  30.         thread.start() ;  
  31.         try {  
  32.             Thread.sleep(1000);  
  33.         } catch (InterruptedException e) {  
  34.             e.printStackTrace();  
  35.         }  
  36.         t.m2();  
  37.     }  
  38. }  
  39. </span></span>  

生产者与消费者实例:

[html] view plain copy

 print?

  1. <span style="font-family:Microsoft YaHei;">package thread;  
  2.   
  3. public class ProducerConsumer {  
  4.   
  5.     public static void main(String[] args) {  
  6.         SyncStack ss = new SyncStack() ;  
  7.         Producer p = new Producer(ss) ;  
  8.         Consumer c = new Consumer(ss) ;  
  9.         new Thread(p).start();  
  10.         new Thread(c).start();  
  11.     }  
  12. }  
  13.   
  14. class WoTou {  
  15.     int id ;  
  16.     WoTou(int id) {  
  17.         this.id = id ;  
  18.     }  
  19.     public String toString() {  
  20.         return "id = " + this.id ;  
  21.     }  
  22. }  
  23.   
  24. class SyncStack {  
  25.     int index = 0 ;  
  26.     WoTou[] arrWt = new WoTou[6] ;  
  27.       
  28.     public synchronized void push(WoTou wt) {  
  29.         while(index == arrWt.length) {  
  30.             try {  
  31.                 this.wait();  
  32.             } catch (InterruptedException e) {  
  33.                 // TODO Auto-generated catch block  
  34.                 e.printStackTrace();  
  35.             }  
  36.         }  
  37.         this.notify();  
  38.         arrWt[index] = wt ;  
  39.         index ++ ;  
  40.     }  
  41.       
  42.     public synchronized WoTou pop() {  
  43.         while(index == 0) {  
  44.             try {  
  45.                 this.wait();  
  46.             } catch (InterruptedException e) {  
  47.                 e.printStackTrace();  
  48.             }  
  49.         }  
  50.         this.notify();  
  51.         index -- ;  
  52.         return arrWt[index] ;  
  53.     }  
  54. }  
  55.   
  56. class Producer implements Runnable {  
  57.       
  58.     SyncStack s = null ;  
  59.       
  60.     public Producer(SyncStack s) {  
  61.         this.s = s ;  
  62.     }  
  63.   
  64.     @Override  
  65.     public void run() {  
  66.         for(int i=0; i<20; i++) {  
  67.             WoTou wt = new WoTou(i) ;  
  68.             System.out.println("push : " + wt);  
  69.             s.push(wt);  
  70.         }  
  71.     }  
  72. }  
  73.   
  74. class Consumer implements Runnable {  
  75.       
  76.     SyncStack s = null ;  
  77.       
  78.     public Consumer(SyncStack s) {  
  79.         this.s = s ;  
  80.     }  
  81.   
  82.     @Override  
  83.     public void run() {  
  84.         for(int i=0; i<20; i++) {  
  85.             WoTou wt = s.pop() ;  
  86.             System.out.println("pop : " + wt);  
  87.         }  
  88.     }  
  89. }</span>  

wait和sleep的区别
wait时别的线程可以访问锁定对象,调用wait方法的时候必须锁定该对象。sleep时别的线程也不可以访问锁定对象。

时间: 2024-12-12 06:54:38

多线程基础的相关文章

Java多线程基础总结七:ReentrantLock

之前总结了部分无锁机制的多线程基础,理想的状态当然是利用无锁同步解决多线程程序设计的问题.但是实际碰到的问题使得很多情 况下,我们不得不借助锁同步来保证线程安全.自从JDK5开始,有两种机制来屏蔽代码块在并行访问的干扰,synchronized关键字已经介绍 过了部分内容,所以这次简单的说说另一种锁机制:ReentrantLock. 对于synchronized的缺点之前也简单的说了一些,实际使用中比较烦扰的几点是:a.只有一个"条件"与锁相关联,这对于大量并发线程 的情况是很难管理(

多线程基础(一)基础中的基础

多线程基础: 先上个以下关于进程.线程和任务的基本的概念的概括图:     进程:      系统中正在运行的一个应用程序(一种状态).      每个进程之间是相互独立的,每个进程在其受保护专用的内存空间内.   线程:      一个进程要想执行任务,必须要有线程(每个进程至少有一条线程)      一个进程所有的任务都是在线程中执行的.   线程的串行      一个线程中的任务的执行是串行的      如果在一个线程中执行多个任务,那么只能一个一个按顺序执行这些任务      同一个时间

多线程基础(五)NSThread线程通信

5.多线程基础 线程间通信 什么叫线程间通信 在一个进程中,线程往往不是孤立存在的,多个线程之间需要经常进行通信 线程间通信的体现 1个线程传递数据给另一个线程 在1个线程中执行完特定任务后, 线程间通信的体现 1个线程传递数据给另1个线程 在1个线程中执行完特定任务后,转到另1个线程继续执行任务 线程间通信常用方法 perform执行 selector选择器 - (void)performSelectorOnMainThread:(SEL)aSelectorwithObject:(id)arg

Java多线程基础总结八:ReentrantReadWriteLock

说到ReentrantReadWriteLock,首先要做的是与ReentrantLock划清界限.它和后者都是单独的实现,彼此之间没有继承或实现的关系. 然后就是总结这个锁机制的特性了: (a).重入方面其内部的WriteLock可以获取ReadLock,但是反过来ReadLock想要获得WriteLock则永远都不要想. (b).WriteLock可以降级为ReadLock,顺序是:先获得WriteLock再获得ReadLock,然后释放WriteLock,这时候线程将保持Readlock的

Java多线程基础总结九:Mina窥探(1)

一直以来的多线程的基础总结都是脱离应用的,但是要说多线程的应用就不能不说Mina.Apache Mina作为一个高性能的Java异步并发网 络通讯框架,其内部的多线程的设计和实现可谓是学习多线程的良药.手上的Mina源码是svn剪下来的最新的代码,mvn转化成eclipse项目 后导入mina-core的源码看看多线程的应用吧. 首先简单的介绍在org.apache.mina.core.service包里的核心接口之一:IoService.这个接口是对于服务器端接收连接和客户端发起连 接这两种服

Java多线程基础总结三: volatile

前面的两篇总结简单的说明了同步的一些问题,在使用基础的同步机制中还有两个可以分享的技术:volatile关键字和ThreadLocal.合 理的根据场景利用这些技术,可以有效的提高并发的性能,下面尝试结合自己的理解叙述这部分的内容,应该会有理解的偏差,我也会尽量 的在完善自己理解的同时同步更新文章的错误. 或许在知道synchronized配和对象内部锁的机制以后,可以提高写出正确同步的并发程序成功率,但是这时候会遇到另一个大问题:性 能!是的,对于 synchronized带来的可能庞大的性能

Java多线程基础总结一: synchronized(1)

最近写关于并发的小应用,才发现真的该好好的正视java的多线程了.之前没有深入的掌握,用起来也是那么的吃力.作为J2SE里面为 数不多的重要难点之一,多线程应用一直是我以敬畏的心态去尽量避开的,只是通过一些实例掌握一些简单的应用.这段时间会多用点时间 去掌握,有需要写下来的我也会通过这种方式既分享又加深理解. 首先这篇只涉及基础的知识整理,对于并发包java.util.concurrent内的线程池和锁我会看情况在之后的总结中写点东西.对于进程的 概念我们都很熟悉,它是应用程序级的隔离,不同的应

java多线程基础(synchronize关键字)

基础知识 多线程实现方法 使用Thread创建线并启动线程 使用Runnable创建并启动线程 使用内部类创建线程 线程的方法 线程优先级 守护线程 sleep方法 yield方法 join方法 线程同步 基础知识 线程:进程(process)就是一块包含了某些资源的内存区域.操作系统利用进程把它的工作划分为一些功能单元. 线程:进程中所包含的一个或多个执行单元称为线程(thread).进程还拥有一个私有的虚拟地址空间,该空间仅能被它所包含的线程访问. 线程和进程的区别如下: 1)一个进程至少有

C#编程总结(二)多线程基础

无论您是为具有单个处理器的计算机还是为具有多个处理器的计算机进行开发,您都希望应用程序为 用户提供最好的响应性能,即使应用程序当前正在完成其他工作.要使应用程序能够快速响应用户操作 ,同时在用户事件之间或者甚至在用户事件期间利用处理器,最强大的方式之一是使用多线程技术. 多线程:线程是程序中一个单一的顺序控制流程.在单个程序中同时运行多个线程完成不同的工 作,称为多线程.如果某个线程进行一次长延迟操作, 处理器就切换到另一个线程执行.这样,多个线 程的并行(并发)执行隐藏了长延迟,提高了处理器资

Java多线程基础总结四:ThreadLocal

说到ThreadLocal,首先说说这个类的命名.直观上看好像是个Thread的什么亲戚,但其实它想表达的意思是线程本地变量,也就是说每 个线程自己的变量.它作为一个JDK5以后支持范型的类,主要是想利用范型把非线程安全的共享变量,封装成绑定线程的安全不共享变量. 这样的解释我想我们多半能猜出它的实现思路:把一个共享变量在每个线程使用时,初始化一个副本,并且和线程绑定.以后所有的线程对 共享变量的操作都是对线程内部那个副本,完全的线程内部变量的操作. 要实现这样功能类的设计,主要技术点是要能把副