java并发编程——共享资源的操作

来源:互联网 发布:淘宝买家号权重是什么 编辑:程序博客网 时间:2024/05/20 19:17

一、并发编程产生的问题

并发编程给程序的设计带来的巨大的好处,但多线程的出现也同样带来了一些问题。

因为线程执行的时间是不确定的,所以,当不同的线程共同访问某一共享资源的时候,可以对共享资源的操作产生错误。

比如:有一共享资源整型num,如果有几个线程同时对其做减1操作。假设当num=90时,线程一对其做减一操作,其从内存中取出num=90,然后到cpu进行减法操作。

这个时候,线程一挂起,线程二开始执行,线程二从内存中取出num=90,对其进行减一操作,num变为了89,。而线程切换到线程一的时候,线程一继续执行,在cpu中做减法操作,num变为89。

也就是执行了两次减一操作,当时共享资源num只是从90变为了89.


二、如何解决这一问题——互斥量操作

1、为了保护资源,采用了加锁的方式。当资源被一个任务使用的时候,对其进行加锁操作。只用当前任务完成,才释放锁。下一个任务才能访问该资源。

在java中使用synchronized关键字的形式控制资源的访问。

2、共享资源。在java中共享资源一般是以对象的形式存在内存片段的。但也可以是文件,输入输出端口,或者是打印机。

3、synchronized的使用

(1)将方法标记为synchronized,如果某个任务处于一个标记为synchroenized的方法的调用中,那么在这个线程从该方法返回之前,其他所有要调用类中任何标记为synchronized方法的线程都会被阻塞。

(2)临界区

有时,希望防止多个线程同时访问方法内部的部分代码,而不是防止访问整个方法。

通过这种方法,分离出来的代码段称为临界区,它使用synchronized关键字建立。

synchronized被用来指定某个对象,此对象的锁被用来对花括号内的代码进行同步控制。

synchronized(对象)

{

    需要控制的代码!

}

这种方法叫做同步控制块,通过同步控制块,而不是对整个方法进行同步控制,可以使得多个任务访问对象的时间性能得到显著提高。


使用一对象,作为锁

package com.xiancheng; class task1 implements Runnable{ private int num = 100;Object o = new Object();public  void run() {while(num>0){synchronized(o){if(num>0){try{ Thread.sleep(10);}catch(InterruptedException e){}   System.out.println(Thread.currentThread().getName()+"........"+num--);}}}}   }  class task2 implements Runnable{ private int num = 100;//Object o = new Object();public  void run() {while(num>0){synchronized(this){if(num>0){try{ Thread.sleep(10);}catch(InterruptedException e){}   System.out.println(Thread.currentThread().getName()+"........"+num--);}}}}   }class task2 implements Runnable{    public void run()   {   for(int z=0;z<=10;z++)   {   for(int y=0;y<=99999999;y++){}System.out.println(Thread.currentThread().getName()+"....z="+z);   }  }   }public class hello {public static void main(String[] args){task1 t1= new task1(); task2 t2 = new task2();Thread nt1 = new Thread(t1);Thread nt2 = new Thread(t1);Thread nt3 = new Thread(t1);nt1.start();nt2.start();nt3.start();}}


0 0