java点点(一)

进程与线程

        进程指一个应用程序的执行过程,它执有资源(内存)和线程。进程是资源分配的基本单位。每一个进程都拥有一个虚拟的完整的地址空间,并且不同的进程的地址空间是不同的。
        线程是程序中一个单一的顺序控制流程,进程内一个相对独立的、可调度的执行单元,是系统独立调度和分派CPU资源的基本单位。在单个程序中同时运行多个线程完成不同的工作,称为多线程。一个进程内的不同线程共享同一块地址空间。
        例如对于一个Android应用来说,一个应用就是一个进程。在应用运行时,不但可以响应用户的点击,同时还可以访问网络。这就是因为响应用户点击和访问网络是运行在两个不同的线程中。系统会快速地在两个线程之间来回的切换,从而不会使用户感觉到卡。
        当一个进程中含有多个线程时,这些线程会操作同一块内存(这些线程所属的进程所执有的内存)。因此,多线程可能会导致内存中的数据的混乱,从而出现一些莫名其妙的数据。

线程的终止

        Thread的run()执行完毕后,线程便自动终止。但有些时候线程会需要线程进行不断地循环执行。在此种情况下,如果想要终止线程可以通过设置旗标的方式进行。
        Thread.stop():立刻中止线程。无论该run()方法中是否还有别的代码未执行。不停止释放线程中的资源。
        interrupt():向线程发送一个中止信号,并不会立即停止线程。调用该方法后,Thread.isInterrupted()返回true。但有例外情况:如果当前线程调用了join()系列或者sleep()系列方法,再调用interrupt()时,join和sleep()会抛出异常(InterruptedException),并且isInterrupted()返回的依旧是false。当线程中调用了Object.wait()系列方法时也是由此。

Object

        在Object类中,含有wait(),notify(),notifyAll()三个方法,它们主要是用于线程同步的。

        在某一线程中调用wait()时,可以使用该线程进入等待状态,直到在别的地方调用了该Object的notify或者notifyAll()。

        notifyAll()和notify()用于唤醒通过该Object对象调用wait()而进行等待状态的线程。只不过前者只是随机唤醒某一个,而后者是唤醒所有的。示例如下:

线程P:

[java]  view plain copy 在CODE上查看代码片 派生到我的代码片
  1. public class ProduceThread extends Thread {  
  2.   
  3.     @Override  
  4.     public void run() {  
  5.         while (true) {  
  6.             synchronized (Main.lockObj) {  
  7.                 while (Main.buf >= 1000) {  
  8.                     try {  
  9.                         Main.lockObj.wait();  
  10.                     } catch (InterruptedException e) {  
  11.                         e.printStackTrace();  
  12.                     }  
  13.                 }  
  14.                 Main.buf++;  
  15.                 System.out.println(getName() + "--操作了buf:" + Main.buf);  
  16.                 Main.lockObj.notifyAll();  
  17.             }  
  18.         }  
  19.     }  
  20. }  
线程C

[java]  view plain copy 在CODE上查看代码片 派生到我的代码片
  1. public class CustomThread extends Thread {  
  2.   
  3.     @Override  
  4.     public void run() {  
  5.         while (true) {  
  6.             synchronized (Main.lockObj) {  
  7.                 while (Main.buf <= 0) {  
  8.                     try {  
  9.                         Main.lockObj.wait();  
  10.                     } catch (InterruptedException e) {  
  11.                         e.printStackTrace();  
  12.                     }  
  13.                 }  
  14.                 Main.buf--;  
  15.                 System.out.println(getName() + "--操作了buf:" + Main.buf);  
  16.                 Main.lockObj.notifyAll();  
  17.             }  
  18.         }  
  19.     }  
  20. }  
        对于线程P,C来说,synchronized()时使用的是同一个对象,因此synchronized内容的代码块一次只能有一个线程进行操作,从而保证了一次只会有一个线程对Main.buf进行操作,保证了数据的正确性。

        在Main.lockObj.wait()外面仍旧套了一层while循环。这是为了保证在线程被唤醒时仍旧会进行判断,使线程只有在满足条件的情况下才会执行下面的代码。

        假设将内层while循环换成if。有两个线程C,分别为c1,c2。假设某时刻c1正在执行,且此时buf为1。当c1执行完后,会唤醒p1与c2。并且系统调动的仍旧是c1,只不过c1在进入if块时进入wait状态,系统重新选择了p1。p1执行一次时,唤醒了wait状态的c1。只不过系统一直会执行p1直到p1的if判断成立,使p1进入wait。此时,系统调用c2(注意,c2执行一个循环后p1被唤醒,且c1仍旧处于唤醒状态,且代码停留在wait()处)。当c2将buf的值修改成0后,c2也会进入到wait状态。系统又选择了c1,c1对buf--操作时,buf就变成了-1(c2将buf的值变成了1),并且将c2唤醒。c2再次执行buf--后,buf会成为-2。

        如果使用了while循环就不会出现上述情况,因为每一个线程被唤醒后的第一件事就是进行再次判断,保证了自己执行时是满足条件的。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值