java多线程的思考

原创 2012年03月23日 00:32:06

----------- android培训java培训、java学习型技术博客、期待与您交流! ------------

    之前的学习中,一直是在解决单线程的问题,学完了多线程,更觉计算机技术的美妙,线程是操作系统的概念,也称为轻量级进程,是cpu的基本使用单元,由线程ID,程序计数器,寄存器和堆栈组成,多个线程可以共享代码段,数据段等等资源;传统的进程就是单线程,它们都独享数据段等资源,可称为重量级进程。一个线程包括5种状态,即新建状态:通过new关键字建立;就绪状态:线程调用start()等待cpu分配执行权;运行状态:一旦获取执行权就运行线程内部定义的run()方法,实现其功能;阻塞状态:线程在运行过程中需要等待输入输出操作,或调用了wait(),sleep()即进入临时等待,将执行权让给其它线程;死亡状态:线程执行完即结束生命周期。
    java提供两种方法实现多线程,第一种方法:继承Thread类,Thread类已经具备运行多线程所需的资源,只需复写该类的run()方法,把线程将要实现功能的代码放入其中,创建线程并调用start()方法启动线程,即可与其它线程交替使用cpu资源;代码如下:
class MyThread extends Thread{
      private String name;
      MyThread(String name){
      this.name = name;
      } 
      public void run(){
        for(int i=0;i<9;i++){
           System.out.println(i);
        }
      }
}
class MyThreadDemo{
      MyThread mt = new MyThread("newThread");
      mt.start();
}
第二种方法:实现Runnble接口,Runnble接口只有一个方法run(),实现接口时必须自己定义该方法(复写该方法),如果运行通过实现该接口的多线程,则需要借助Thread类,因为Runnble接口没有提供支持多线程的方法,必须借助Thread类的框架,通过该类的构造函数public Thread(Runnble target)来实现;代码如下:
class MyRunnbleThread implements Runnble{
     public void run(){
           for(int i=0;i<10;i++){
           System.out.println(i); 
           }
     }
}
class MyRunnbleThreadDemo{
     MyRunnbleThread mr = new Thread(new MyRunnbleThread);
     mr.start();
}
     在多线程中经常会遇到资源共享的问题,假设两个线程同时访问一个数据区,一个读数据,一个写数据,如果一个线程在读数据前另一个线程修改了数据,则读数据线程读到的就不是原始数据而是修改过的数据,这样就产生错误,安全问题就产生了,事实上多线程主要就是解决安全问题,为了解决此问题,java中采用了代码同步的方法,即为共享数据加锁,当一个线程访问数据时,拒绝另一个线程同时访问,知道数据空闲,在设计多线程模式中,解决线程冲突都是才用synchronized关键字实现,保证在一段时间内只能有一个线程访问这段代码,实现方式为同步函数或同步代码块,下面已实际应用中的单例设计模式来分析:
class Single{
    private Single(){}
    private static Single s=null;
    private Static getInstanse(){
       if(s=null){
         synchronized(Single.class){
            if(s=null)//线程1,线程2
               s=new Single();
            return s;
         }  
    }
}
因为该类不能创建对象,只能通过getInstanse()获取已经创建的唯一对象,当多个线程使用该方法时,线程1执行到第二个if处cpu切换到线程2,线程2执行到此处也停止,此时线程1重新获取资格继续执行创建一个对象,当线程2也重新获取资格后不再判断,再次创建了一个对象,这样,与单例设计的初衷就相违背,整个程序的执行都将受到影响,若将代码(if(s=null)s=new Single();return s;)封装起来就会避免安全隐患的发生。
    同时要注意,synchronized(Single.class)这个所必须要被一个对象持有,可以是Object,this,.class,但具体用那个,得看需求,像上面这个代码只需保证是一个唯一的对象即可,若同一块数据区,在不同的代码中被使用,必须要用同一把所对这两块代码进行加锁,即使用同一个对象,另外在使用锁机制时,稍有不慎就会发生死锁现象,看下面代码示例:
class Test implement Runnable{
   private boolean flag;
   Test(boolean flag){
      this.flag = flag;
   }
   public void run(){
      if(flag){
         synchronized(locka){
            System.out.println("if locka");
            synchronized(lockb){
                System.out.println("else lockb"); 
            }
         }
     else{
          synchronized(lockb){
            System.out.println("if lockb");
            synchronized(locka){
                System.out.println("else locka"); 
            }
     }
      }
   }
}
上例中,两把锁互相调用都在等对方释放,就会产生死锁问题,所以在实际开发中必须分析清楚那些是共享数据,并找到正确的锁进行同步。
     java中还定义了几个方法用于控制线程的执行顺序:wait(),notify(),notifyAll(), 这些方法可用于线程间通讯,由于任何对象都可作为监视器对象,所以任何对象都可以调用这些方法,但这些方法只能用在被锁控制的代码块或方法中。这些方法又可称为线程的等待唤醒机制,当一个线程只想到某处需要将cpu执行权转让给它人时,调用wait()方法,适当的时候对方会调用notify()方法将其唤醒,当再次获取cpu执行权后继续执行,保证了数据的安全性。
     综上所属,多线程技术是java中最绚丽的技术,也是最难以琢磨的技术,在实际开发中需重点关注,稍有不慎,将有严重后果。所以在写代码之前要详细分析,找出关键因素,理清思路,开发才会更轻松。

----------------------- android培训java培训、java学习型技术博客、期待与您交流! ----------------------

详情请查看:http://edu.csdn.net/heima


 

读《面向对象的思考过程》作者matt Weisfeld

最近接触了很多java代码,开始于机缘巧合,读了《java编程思想》的大概前四分之一,这比我读《C++primer》还要多了,两本都是大部头,我能完整读完还需毅力。惊讶于两门语言语法非常的相似,之前对...
  • czl389
  • czl389
  • 2017年02月22日 11:36
  • 997

工作中四种重要的能力------谈谈工作两年后的一点思考

毕业已经两年多了, 经历了职场新人的最初阶段,打算写下自己的一些思考。 欢迎各位职场老鸟拍砖、指正。          第一: 持续的热情          从严格意义上来讲, 热情应该不能算一种...
  • stpeace
  • stpeace
  • 2015年11月09日 23:41
  • 1763

对java多线程的一点思考

关于java多线程的一点思考
  • a915650754
  • a915650754
  • 2015年06月19日 17:26
  • 679

叔本华系列之(一)论独立的思考

即使是藏书最为丰富的图书馆,如果里面的书籍胡乱摆放,那么它的实际用处还不如一个收藏不多、但却整理得井井有条的小图书室。同样道理,如果大量的知识没有经过自己细心地思考加工,那么它的价值也远远逊色于数量较...
  • c_trekman
  • c_trekman
  • 2016年11月26日 14:55
  • 189

JMeter学习笔记21-如何添加思考时间

本文来介绍,JMeter如何插入思考时间。前面介绍过一个真实的性能测试场景,是需要加入思考时间,来模拟真实用户行为。本文就来介绍,如何在三个请求之间添加思考时间。 1. 在Test Plan下新建一...
  • u011541946
  • u011541946
  • 2017年05月05日 16:13
  • 2440

Java程序员应该常思考的问题

Java Serial 1. Java基础问答 2. Java Generic 3. Latch VS Barrier 4. AtomicInteger, BlockingQueue and Fork...
  • sxb0841901116
  • sxb0841901116
  • 2014年04月16日 00:30
  • 1614

《清醒思考的艺术》读后感

咱们大部分人都是普通人,一些常见的思维漏洞我们也不免存在,这本书讲了50多种常见的常见的思维习惯并有小故事帮助我们理解这些习惯中的漏洞,让我们对事物有更加清楚的认识。 一、幸存偏误 概念:由于日常...
  • HEJI1103
  • HEJI1103
  • 2016年07月05日 18:52
  • 1627

读书笔记:逆向思考的艺术

这本书的作者是Humphrey B. Neill,本来想查一下wiki看看这个人的介绍,居然没查到。逆向思考可以简单表述为:不落他人窠臼,相信自己的想法,思考问题的时候要尽量做到特立独行,避免思想的雷...
  • carolzhang8406
  • carolzhang8406
  • 2015年06月01日 10:45
  • 1035

LoadRunner性能测试-思考时间

LoadRunner思考时间  一、virtual user generator(脚本录制与设置)        1、在录制脚本的时候LoadRunner会自动记录录制者在录制软件系统...
  • liuyuzhu111
  • liuyuzhu111
  • 2015年11月12日 19:38
  • 1183

Chrome多线程模型的优缺点

开源是口好东西,它让这个充斥着大量工业垃圾代码和教材玩具代码的行业,多了一些艺术气息和美的潜质。它使得每个人,无论你来自米国纽约还是中国铁岭,都有机会站在巨人的肩膀上,如果不能,至少也可以抱一把大腿。...
  • Beyond_cn
  • Beyond_cn
  • 2014年12月15日 19:48
  • 2653
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:java多线程的思考
举报原因:
原因补充:

(最多只允许输入30个字)