??xml version="1.0" encoding="utf-8" standalone="yes"?>亚洲欧洲日产国码久在线观看,久久精品国产亚洲av麻豆,亚洲www在线观看http://www.tkk7.com/AntiquMan/category/38695.htmlzh-cnWed, 05 Aug 2009 15:19:10 GMTWed, 05 Aug 2009 15:19:10 GMT60(?队列和线E池单示?http://www.tkk7.com/AntiquMan/archive/2009/08/03/289644.htmlAntiquManAntiquManMon, 03 Aug 2009 10:18:00 GMThttp://www.tkk7.com/AntiquMan/archive/2009/08/03/289644.htmlhttp://www.tkk7.com/AntiquMan/comments/289644.htmlhttp://www.tkk7.com/AntiquMan/archive/2009/08/03/289644.html#Feedback0http://www.tkk7.com/AntiquMan/comments/commentRss/289644.htmlhttp://www.tkk7.com/AntiquMan/services/trackbacks/289644.html

基本演示了线E池和队列的应用

  public class WorkQueue { 
   

   private final int nThreads;//U程池的大小 
   private final PoolWorker[] threads;//用数l实现线E池 
   private final LinkedList queue;//d队列 

  public WorkQueue(int nThreads){ 
     this.nThreads = nThreads; 
     queue = new LinkedList(); 
     threads = new PoolWorker[nThreads]; 

      for (int i=0; i<nThreads;i++){

         threads[i] = new PoolWorker(); 
         threads[i].start();//启动所有工作线E?nbsp;
      } 
  } 

  public void execute(Runnable r) {//

    synchronized(queue) { 
            queue.addLast(r); 
            queue.notify(); 
    } 
  } 

  private class PoolWorker extends Thread {//工作U程c?nbsp;
        public void run() { 
               Runnable r; 
               while (true) { 
                    synchronized(queue) { 
                      while (queue.isEmpty()) {//如果d队列中没有Q务,{待 
                        try{ 
                          queue.wait(); 
                        }catch (InterruptedException ignored){} 
                      }    
                       r = (Runnable) queue.removeFirst();//有Q务时Q取ZQ?nbsp;
                   } 
                   try { 
                       r.run();//执行d 
                   }catch (RuntimeException e) { 
                      // You might want to log something here 
                  } 
              } 
      } 
   } 


 public static void main(String args[]){ 
      WorkQueue wq=new WorkQueue(10);//10个工作线E?nbsp;
      Mytask r[]=new Mytask[20];//20个Q?nbsp;
   
      for(int i=0;i<20;i++){ 
           r[i]=new Mytask(); 
           wq.execute(r[i]); 
      }       
 } 

class Mytask implements Runnable{//d接口 
         public void run(){ 
              String name=Thread.currentThread().getName(); 
              try{ 
                  Thread.sleep(100);//模拟d执行的时?nbsp;
              }catch(InterruptedException e){} 
              System.out.println(name+" executed OK"); 
         } 
  } 



AntiquMan 2009-08-03 18:18 发表评论
]]>
JavaU程Q线E的同步 http://www.tkk7.com/AntiquMan/archive/2009/07/03/285349.htmlAntiquManAntiquManFri, 03 Jul 2009 06:45:00 GMThttp://www.tkk7.com/AntiquMan/archive/2009/07/03/285349.htmlhttp://www.tkk7.com/AntiquMan/comments/285349.htmlhttp://www.tkk7.com/AntiquMan/archive/2009/07/03/285349.html#Feedback0http://www.tkk7.com/AntiquMan/comments/commentRss/285349.htmlhttp://www.tkk7.com/AntiquMan/services/trackbacks/285349.html一、同步问题提?/strong>
 
U程的同步是Z防止多个U程讉K一个数据对象时Q对数据造成的破坏?/div>
例如Q两个线EThreadA、ThreadB都操作同一个对象Foo对象Qƈ修改Foo对象上的数据?/div>
 
public class Foo {
    private int x = 100;

    public int getX() {
        return x;
    }

    public int fix(int y) {
        x = x - y;
        return x;
    }
}
 
public class MyRunnable implements Runnable {
    private Foo foo = new Foo();

    public static void main(String[] args) {
        MyRunnable r = new MyRunnable();
        Thread ta = new Thread(r, "Thread-A");
        Thread tb = new Thread(r, "Thread-B");
        ta.start();
        tb.start();
    }

    public void run() {
        for (int i = 0; i < 3; i++) {
            this.fix(30);
            try {
                Thread.sleep(1);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            System.out.println(Thread.currentThread().getName() + " : 当前foo对象的x? " + foo.getX());
        }
    }

    public int fix(int y) {
        return foo.fix(y);
    }
}
 
q行l果Q?/div>
Thread-A : 当前foo对象的x? 40
Thread-B : 当前foo对象的x? 40
Thread-B : 当前foo对象的x? -20
Thread-A : 当前foo对象的x? -50
Thread-A : 当前foo对象的x? -80
Thread-B : 当前foo对象的x? -80

Process finished with exit code 0
 
从结果发玎ͼq样的输出值明显是不合理的。原因是两个U程不加控制的访问Foo对象q修改其数据所致?/div>
 
如果要保持结果的合理性,只需要达C个目的,是对Foo的访问加以限Ӟ每次只能有一个线E在讉K。这样就能保证Foo对象中数据的合理性了?/div>
 
在具体的Java代码中需要完成一下两个操作:
把竞争访问的资源cFoo变量x标识为privateQ?/div>
同步哪些修改变量的代码,使用synchronized关键字同步方法或代码?/div>
 
二、同步和锁定
 
1、锁的原?/div>
 
Java中每个对象都有一个内|锁
 
当程序运行到非静态的synchronized同步Ҏ上时Q自动获得与正在执行代码cȝ当前实例Qthis实例Q有关的锁。获得一个对象的锁也UCؓ获取锁、锁定对象、在对象上锁定或在对象上同步?/div>
 
当程序运行到synchronized同步Ҏ或代码块时才该对象锁才v作用?/div>
 
一个对象只有一个锁。所以,如果一个线E获得该锁,没有其他线E可以获得锁Q直到第一个线E释放(或返回)锁。这也意味着M其他U程都不能进入该对象上的synchronizedҎ或代码块Q直到该锁被释放?/div>
 
释放锁是指持锁线E退Zsynchronized同步Ҏ或代码块?/div>
 
关于锁和同步Q有一下几个要点:
1Q、只能同步方法,而不能同步变量和c;
2Q、每个对象只有一个锁Q当提到同步Ӟ应该清楚在什么上同步Q也是_在哪个对象上同步Q?/div>
3Q、不必同步类中所有的ҎQ类可以同时拥有同步和非同步Ҏ?/div>
4Q、如果两个线E要执行一个类中的synchronizedҎQƈ且两个线E用相同的实例来调用方法,那么一ơ只能有一个线E能够执行方法,另一个需要等待,直到锁被释放。也是_如果一个线E在对象上获得一个锁Q就没有M其他U程可以q入Q该对象的)cM的Q何一个同步方法?/div>
5Q、如果线E拥有同步和非同步方法,则非同步Ҏ可以被多个线E自p问而不受锁的限制?/div>

6Q、线E睡眠时Q它所持的M锁都不会释放?

7Q、线E可以获得多个锁。比如,在一个对象的同步Ҏ里面调用另外一个对象的同步ҎQ则获取了两个对象的同步锁?/div>
8Q、同步损宛_ƈ发性,应该可能羃同步范围。同步不但可以同步整个方法,q可以同步方法中一部分代码块?/div>
9Q、在使用同步代码块时候,应该指定在哪个对象上同步Q也是说要获取哪个对象的锁。例如:
    public int fix(int y) {
        synchronized (this) {
            x = x - y;
        }
        return x;
    }
 
当然Q同步方法也可以改写为非同步ҎQ但功能完全一LQ例如:
    public synchronized int getX() {
        return x++;
    }
?/div>
    public int getX() {
        synchronized (this) {
            return x;
        }
    }
效果是完全一L?/div>
 
三、静态方法同?/strong>
 
要同步静态方法,需要一个用于整个类对象的锁Q这个对象是是q个c(XXX.class)?/div>
例如Q?/div>
public static synchronized int setName(String name){
      Xxx.name = name;
}
{h?br /> public static int setName(String name){
      synchronized(Xxx.class){
            Xxx.name = name;
      }
}

 
四、如果线E不能不能获得锁会怎么?/strong>
 
如果U程试图q入同步ҎQ而其锁已l被占用Q则U程在该对象上被d。实质上Q线E进入该对象的的一U池中,必须在哪里等待,直到光被释放,该线E再ơ变为可q行或运行ؓ止?/div>
 
当考虑dӞ一定要注意哪个对象正被用于锁定Q?/div>
1、调用同一个对象中非静态同步方法的U程彼此阻塞。如果是不同对象Q则每个U程有自q对象的锁Q线E间彼此互不q预?/div>
 
2、调用同一个类中的静态同步方法的U程彼此阻塞,它们都是锁定在相同的Class对象上?/div>
 
3、静态同步方法和非静态同步方法将永远不会彼此dQ因为静态方法锁定在Class对象上,非静态方法锁定在该类的对象上?/div>
 
4、对于同步代码块Q要看清楚什么对象已l用于锁定(synchronized后面括号的内容)。在同一个对象上q行同步的线E将彼此dQ在不同对象上锁定的U程永q不会彼此阻塞?/div>
 
五、何旉要同?/strong>
 
在多个线E同时访问互斥(可交换)数据Ӟ应该同步以保护数据,保两个U程不会同时修改更改它?/div>
 
对于非静态字D中可更改的数据Q通常使用非静态方法访问?/div>
对于静态字D中可更改的数据Q通常使用静态方法访问?/div>
 
如果需要在非静态方法中使用静态字D,或者在静态字D中调用非静态方法,问题变得非常复杂。已l超出SJCP考试范围了?/div>
 
六、线E安全类
 
当一个类已经很好的同步以保护它的数据Ӟq个cdUCؓ“U程安全?#8221;?/div>
 
即是线E安全类Q也应该特别心Q因为操作的U程是间仍然不一定安全?/div>
 
举个形象的例子,比如一个集合是U程安全的,有两个线E在操作同一个集合对象,当第一个线E查询集合非I后Q删除集合中所有元素的时候。第二个U程也来执行与第一个线E相同的操作Q也许在W一个线E查询后Q第二个U程也查询出集合非空Q但是当W一个执行清除后Q第二个再执行删除显然是不对的,因ؓ此时集合已经为空了?/div>
看个代码Q?/div>
 
public class NameList {
    private List nameList = Collections.synchronizedList(new LinkedList());

    public void add(String name) {
        nameList.add(name);
    }

    public String removeFirst() {
        if (nameList.size() > 0) {
            return (String) nameList.remove(0);
        } else {
            return null;
        }
    }
}
 
public class Test {
    public static void main(String[] args) {
        final NameList nl = new NameList();
        nl.add("aaa");
        class NameDropper extends Thread{
            public void run(){
                String name = nl.removeFirst();
                System.out.println(name);
            }
        }

        Thread t1 = new NameDropper();
        Thread t2 = new NameDropper();
        t1.start();
        t2.start();
    }
}
 
虽然集合对象
    private List nameList = Collections.synchronizedList(new LinkedList());
是同步的Q但是程序还不是U程安全的?/div>
出现q种事g的原因是Q上例中一个线E操作列表过E中无法L另外一个线E对列表的其他操作?/div>
 
解决上面问题的办法是Q在操作集合对象的NameList上面做一个同步。改写后的代码如下:
public class NameList {
    private List nameList = Collections.synchronizedList(new LinkedList());

    public synchronized void add(String name) {
        nameList.add(name);
    }

    public synchronized String removeFirst() {
        if (nameList.size() > 0) {
            return (String) nameList.remove(0);
        } else {
            return null;
        }
    }
}
 
q样Q当一个线E访问其中一个同步方法时Q其他线E只有等待?/div>
 
七、线E死?/strong>
 
死锁对JavaE序来说Q是很复杂的Q也很难发现问题。当两个U程被阻塞,每个U程在等待另一个线E时发生死锁?/div>
 
q是看一个比较直观的死锁例子Q?/div>
 
public class DeadlockRisk {
    private static class Resource {
        public int value;
    }

    private Resource resourceA = new Resource();
    private Resource resourceB = new Resource();

    public int read() {
        synchronized (resourceA) {
            synchronized (resourceB) {
                return resourceB.value + resourceA.value;
            }
        }
    }

    public void write(int a, int b) {
        synchronized (resourceB) {
            synchronized (resourceA) {
                resourceA.value = a;
                resourceB.value = b;
            }
        }
    }
}
 
假设read()Ҏ׃个线E启动,write()Ҏ由另外一个线E启动。读U程拥有resourceA锁,写线E将拥有resourceB锁,两者都坚持{待的话出现死锁?/div>
 
实际上,上面q个例子发生死锁的概率很。因为在代码内的某个点,CPU必须从读U程切换到写U程Q所以,死锁基本上不能发生?/div>
 
但是Q无Z码中发生死锁的概率有多小Q一旦发生死锁,E序死掉。有一些设计方法能帮助避免死锁Q包括始l按照预定义的顺序获取锁q一{略。已l超出SCJP的考试范围?/div>
 
八、线E同步小l?/strong>
 
1、线E同步的目的是ؓ了保护多个线E反问一个资源时对资源的破坏?/div>
2、线E同步方法是通过锁来实现Q每个对象都有切仅有一个锁Q这个锁与一个特定的对象兌Q线E一旦获取了对象锁,其他讉K该对象的U程无法再讉K该对象的其他非同步方法?/div>
3、对于静态同步方法,锁是针对q个cȝQ锁对象是该cȝClass对象。静态和非静态方法的锁互不干预。一个线E获得锁Q当在一个同步方法中讉K另外对象上的同步ҎӞ会获取这两个对象锁?/div>
4、对于同步,要时L醒在哪个对象上同步,q是关键?/div>
5、编写线E安全的c,需要时L意对多个U程竞争讉K资源的逻辑和安全做出正的判断Q对“原子”操作做出分析Qƈ保证原子操作期间别的U程无法讉K竞争资源?/div>
6、当多个U程{待一个对象锁Ӟ没有获取到锁的线E将发生d?/div>
7、死锁是U程间相互等待锁锁造成的,在实际中发生的概率非常的。真让你写个死锁E序Q不一定好使,呵呵。但是,一旦程序发生死锁,E序死掉?/div>

AntiquMan 2009-07-03 14:45 发表评论
]]>Java多线E编E详?/title><link>http://www.tkk7.com/AntiquMan/archive/2009/03/31/263016.html</link><dc:creator>AntiquMan</dc:creator><author>AntiquMan</author><pubDate>Mon, 30 Mar 2009 17:15:00 GMT</pubDate><guid>http://www.tkk7.com/AntiquMan/archive/2009/03/31/263016.html</guid><wfw:comment>http://www.tkk7.com/AntiquMan/comments/263016.html</wfw:comment><comments>http://www.tkk7.com/AntiquMan/archive/2009/03/31/263016.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.tkk7.com/AntiquMan/comments/commentRss/263016.html</wfw:commentRss><trackback:ping>http://www.tkk7.com/AntiquMan/services/trackbacks/263016.html</trackback:ping><description><![CDATA[<p>一Q理解多U程<br /> <br /> 多线E是q样一U机Ӟ它允许在E序中ƈ发执行多个指令流Q每个指令流都称Z个线E,彼此间互相独立?nbsp;<br /> <br /> U程又称量q程Q它和进E一h有独立的执行控制Q由操作pȝ负责调度Q区别在于线E没有独立的存储I间Q而是和所属进E中的其它线E共享一个存储空_q得线E间的通信q较q程单?br /> <br /> 多个U程的执行是q发的,也就是在逻辑?#8220;同时”Q而不是否是物理上的“同时”。如果系l只有一个CPUQ那么真正的“同时”是不可能的,但是׃CPU的速度非常快,用户感觉不到其中的区别,因此我们也不用关心它Q只需要设惛_个线E是同时执行卛_?br /> <br /> 多线E和传统的单U程在程序设计上最大的区别在于Q由于各个线E的控制彼此独立,使得各个U程之间的代码是乱序执行的,由此带来的线E调度,同步{问题,在以后探讨?br /> <br /> <strong>二:在Java中实现多U程</strong><br /> <br /> 我们不妨设想Qؓ了创Z个新的线E,我们需要做些什么?很显Ӟ我们必须指明q个U程所要执行的代码Q而这是在Java中实现多U程我们所需要做的一切!<br /> <br /> 真是奇QJava是如何做到这一点的Q通过c!作ؓ一个完全面向对象的语言QJava提供了类 java.lang.Thread 来方便多U程~程Q这个类提供了大量的Ҏ来方便我们控制自q各个U程Q我们以后的讨论都将围绕q个c进行?nbsp;<br /> <br /> 那么如何提供l?nbsp;Java 我们要线E执行的代码呢?让我们来看一?nbsp;Thread cRThread cL重要的方法是 run() Q它为Thread cȝҎ start() 所调用Q提供我们的U程所要执行的代码。ؓ了指定我们自q代码Q只需要覆盖它Q?br /> <br /> Ҏ一Q?nbsp;Thread c,覆盖Ҏ run()<br /> <br /> 我们在创建的 Thread cȝ子类中重?nbsp;run() ,加入U程所要执行的代码卛_?br /> 下面是一个例子:</p> <blockquote><span>CODE:</span> <hr /> <pre><br /> public class MyThread extends Thread <br /> <br />     public void run() <br /> <br />     }<br /> <br />     public static void main(String args[]) <br /> <br /> }<br /> </pre> <hr /> </blockquote> <p><br /> <br /> q种Ҏ单明了,W合大家的习惯,但是Q它也有一个很大的~点Q那是如果我们的类已经从一个类l承Q如程序必ȝ承自 Applet c)Q则无法再?nbsp;Thread c,q时如果我们又不惛_立一个新的类Q应该怎么办呢Q?br /> <br /> 我们不妨来探索一U新的方法:我们不创?nbsp;Thread cȝ子类Q而是直接使用它,那么我们只能我们的Ҏ作ؓ参数传递给 Thread cȝ实例Q有点类似回调函数。但?nbsp;Java 没有指针Q我们只能传递一个包含这个方法的cȝ实例。那么如何限制这个类必须包含q一Ҏ呢?当然是用接口!Q虽然抽象类也可满Q但是需要承,而我们之所以要采用q种新方法,不就是ؓ了避免承带来的限制吗?Q?br /> <br /> <br /> Java 提供了接?nbsp;java.lang.Runnable 来支持这U方法?br /> <br /> Ҏ二:实现 Runnable 接口<br /> <br /> <br /> Runnable 接口只有一个方?nbsp;run()Q我们声明自qcd?nbsp;Runnable 接口q提供这一ҎQ将我们的线E代码写入其中,完成了q一部分的Q务?br /> <br /> 但是 Runnable 接口q没有Q何对U程的支持,我们q必d?nbsp;Thread cȝ实例Q这一炚w过 Thread cȝ构造函?br /> public Thread(Runnable target);来实现?br /> <br /> 下面是一个例子:</p> <blockquote><span>CODE:</span> <hr /> <pre><br /> public class MyThread implements Runnable <br /> <br />     public void run()  <br /> <br />     }<br /> <br />     public static void main(String args[]) <br /> <br /> }<br /> </pre> <hr /> </blockquote> <p><br /> <br /> 严格地说Q创?nbsp;Thread 子类的实例也是可行的Q但是必L意的是,该子cdL有覆?nbsp;Thread cȝ run ҎQ否则该U程执行的将是子cȝ run ҎQ而不是我<br /> <br /> 们用以实现Runnable 接口的类?nbsp;run ҎQ对此大家不妨试验一下?br /> <br /> 使用 Runnable 接口来实现多U程使得我们能够在一个类中包Ҏ有的代码Q有利于装Q它的缺点在于,我们只能使用一套代码,若想创徏多个U程q各个U程执行不同的代码,则仍必须额外创徏c,如果q样的话Q在大多数情况下也许q不如直接用多个cd别?nbsp;Thread 来得紧凑?br /> <br /> <br /> lg所qͼ两种Ҏ各有千秋Q大家可以灵z运用?br /> <br /> 下面让我们一h研究一下多U程使用中的一些问题?br /> <br /> <strong>三:U程的四U状?/strong><br /> <br /> 1. 新状态:U程已被创徏但尚未执行(start() 未被调用)?br /> <br /> 2. 可执行状态:U程可以执行Q虽然不一定正在执行。CPU 旉随时可能被分配给该线E,从而得它执行?br /> <br /> 3. M状态:正常情况?nbsp;run() q回使得U程M。调?nbsp;stop()?nbsp;destroy() 亦有同样效果Q但是不被推荐,前者会产生异常Q后者是强制l止Q不会释N?br /> <br /> 4. d状态:U程不会被分?nbsp;CPU 旉Q无法执行?br /> <br /> <strong>四:U程的优先 </strong><br /> <br /> U程的优先代表该线E的重要E度Q当有多个线E同时处于可执行状态ƈ{待获得 CPU 旉ӞU程调度pȝҎ各个U程的优先来决定给谁分?nbsp;CPU 旉Q优先高的U程有更大的Z获得 CPU 旉Q优先低的U程也不是没有机会,只是Z要小一些Ş了?br /> <br /> <br /> 你可以调?nbsp;Thread cȝҎ getPriority() ?nbsp;setPriority()来存取线E的优先U,U程的优先界于1(MIN_PRIORITY)?0(MAX_PRIORITY)之间Q缺省是5(NORM_PRIORITY)?br /> <br /> <br /> <strong>五:U程的同?/strong><br /> <br /> ׃同一q程的多个线E共享同一片存储空_在带来方便的同时Q也带来了访问冲H这个严重的问题。Java语言提供了专门机制以解决q种冲突Q有效避免了同一个数据对象被多个U程同时讉K?br /> <br /> <br /> ׃我们可以通过 private 关键字来保证数据对象只能被方法访问,所以我们只需针对Ҏ提出一套机Ӟq套机制是 synchronized 关键字,它包括两U用法:synchronized Ҏ?nbsp;synchronized 块?br /> <br /> <br /> <br /> 1. synchronized ҎQ通过在方法声明中加入 synchronized关键字来声明 synchronized Ҏ。如Q?br /> <br /> public synchronized void accessVal(int newVal);<br /> <br /> <br /> synchronized Ҏ控制对类成员变量的访问:每个cd例对应一把锁Q每?nbsp;synchronized Ҏ都必获得调用该Ҏ的类实例的锁方能执行Q否则所属线E阻塞,?br /> <br /> 法一旦执行,q占该锁,直到从该Ҏq回时才锁释放Q此后被d的线E方能获得该锁,重新q入可执行状态。这U机制确保了同一时刻对于每一个类实例Q其所有声明ؓ synchronized 的成员函C臛_只有一个处于可执行状态(因ؓ臛_只有一个能够获得该cd例对应的锁)Q从而有效避免了cL员变量的讉K冲突Q只要所有可能访问类成员变量的方法均被声明ؓ synchronizedQ?br /> <br /> <br /> ?nbsp;Java 中,不光是类实例Q每一个类也对应一把锁Q这h们也可将cȝ静态成员函数声明ؓ synchronized Q以控制其对cȝ静态成员变量的讉K?br /> synchronized Ҏ的缺P若将一个大的方法声明ؓsynchronized 会大大影响效率Q典型地Q若线E类的方?nbsp;run() 声明?nbsp;synchronized Q由于在U程的整个生命期内它一直在q行Q因此将D它对本类M synchronized Ҏ的调用都永远不会成功。当然我们可以通过访问类成员变量的代码放C门的Ҏ中,其声明?nbsp;synchronized Qƈ在主Ҏ中调用来解决q一问题Q但?nbsp;Java 为我们提供了更好的解军_法,那就?nbsp;synchronized 块?br /> <br /> 2. synchronized 块:通过 synchronized关键字来声明synchronized 块。语法如下: <br /> synchronized(syncObject) <br /> <br /> <br /> <br /> synchronized 块是q样一个代码块Q其中的代码必须获得对象 syncObject Q如前所qͼ可以是类实例或类Q的锁方能执行,具体机制同前所q。由于可以针对Q意代码块Q且可Q意指定上锁的对象Q故灉|性较高?br /> <br /> <br /> <br /> <strong>六:U程的阻?/strong><br /> <br /> <br /> <br /> Z解决对共享存储区的访问冲H,Java 引入了同步机Ӟ现在让我们来考察多个U程对共享资源的讉KQ显然同步机制已l不够了Q因为在L时刻所要求的资源不一定已l准备好了被讉KQ反q来Q同一时刻准备好了的资源也可能不止一个。ؓ了解册U情况下的访问控刉题,Java 引入了对d机制的支持?br /> <br /> <br /> d指的是暂停一个线E的执行以等待某个条件发生(如某资源qAQ,学过操作pȝ的同学对它一定已l很熟悉了。Java 提供了大量方法来支持dQ下面让我们逐一分析?br /> <br /> <br /> <br /> 1. sleep() ҎQsleep() 允许 指定以毫Uؓ单位的一D|间作为参敎ͼ它得线E在指定的时间内q入d状态,不能得到CPU 旉Q指定的旉一q,U程重新q入可执行状态?br /> <br /> 典型圎ͼsleep() 被用在等待某个资源就l的情ŞQ测试发现条件不满后,让线E阻塞一D|间后重新试Q直到条件满ؓ止?br /> <br /> <br /> 2. suspend() ?nbsp;resume() ҎQ两个方法配套用,suspend()使得U程q入d状态,q且不会自动恢复Q必d对应的resume() 被调用,才能使得U程重新q入可执行状态。典型地Qsuspend() ?nbsp;resume() 被用在等待另一个线E生的l果的情形:试发现l果q没有生后Q让U程dQ另一个线E生了l果后,调用 resume() 使其恢复?br /> <br /> <br /> 3. yield() ҎQyield() 使得U程攑ּ当前分得?nbsp;CPU 旉Q但是不使线E阻塞,即线E仍处于可执行状态,随时可能再次分得 CPU 旉。调?nbsp;yield() 的效果等价于调度E序认ؓ该线E已执行了够的旉从而{到另一个线E?br /> <br /> <br /> <br /> 4. wait() ?nbsp;notify() ҎQ两个方法配套用,wait() 使得U程q入d状态,它有两种形式Q一U允?nbsp;指定以毫Uؓ单位的一D|间作为参敎ͼ另一U没有参敎ͼ前者当对应?nbsp;notify() 被调用或者超出指定时间时U程重新q入可执行状态,后者则必须对应?nbsp;notify() 被调用?br /> <br /> 初看h它们?nbsp;suspend() ?nbsp;resume() ҎҎ有什么分别,但是事实上它们是截然不同的。区别的核心在于Q前面叙q的所有方法,d旉不会释放占用的锁Q如果占用了的话Q,而这一Ҏ法则相反?br /> <br /> <br /> <br /> 上述的核心区别导致了一pd的细节上的区别?br /> <br /> 首先Q前面叙q的所有方法都隶属?nbsp;Thread c,但是q一对却直接隶属?nbsp;Object c,也就是说Q所有对象都拥有q一Ҏ法。初看v来这十分不可思议Q但是实际上却是很自然的Q因一Ҏ法阻塞时要释攑֍用的锁,而锁是Q何对象都h的,调用L对象?nbsp;wait() ҎDU程dQƈ且该对象上的锁被释放。而调?nbsp;L对象的notify()Ҏ则导致因调用该对象的 wait() Ҏ而阻塞的U程中随机选择的一个解除阻塞(但要{到获得锁后才真正可执行Q?br /> <br /> 其次Q前面叙q的所有方法都可在M位置调用Q但是这一Ҏ法却必须?nbsp;synchronized Ҏ或块中调用,理由也很单,只有在synchronized Ҏ或块中当前线E才占有锁,才有锁可以释放。同L道理Q调用这一Ҏ法的对象上的锁必Mؓ当前U程所拥有Q这h有锁可以释放。因此,q一Ҏ法调用必L|在q样?nbsp;synchronized Ҏ或块中,该方法或块的上锁对象是调用q一Ҏ法的对象。若不满一条gQ则E序虽然仍能~译Q但在运行时会出现IllegalMonitorStateException 异常?br /> <br /> <br /> <br /> wait() ?nbsp;notify() Ҏ的上q特性决定了它们l常和synchronized Ҏ或块一起用,它们和操作pȝ的进E间通信机制作一个比较就会发现它们的怼性:synchronizedҎ或块提供了类g操作pȝ原语的功能,它们的执行不会受到多U程机制的干扎ͼ而这一Ҏ法则相当?nbsp;block 和wakeup 原语Q这一Ҏ法均声明?nbsp;synchronizedQ。它们的l合使得我们可以实现操作pȝ上一pd_֦的进E间通信的算法(如信号量法Q,q用于解军_U复杂的U程间通信问题?br /> <br /> <br /> <br /> 关于 wait() ?nbsp;notify() Ҏ最后再说明两点Q?br /> <br /> W一Q调?nbsp;notify() ҎD解除d的线E是从因调用该对象的 wait() Ҏ而阻塞的U程中随机选取的,我们无法预料哪一个线E将会被选择Q所以编E时要特别小心,避免因这U不定性而生问题?br /> <br /> W二Q除?nbsp;notify()Q还有一个方?nbsp;notifyAll() 也可起到cM作用Q唯一的区别在于,调用 notifyAll() Ҏ把因调用该对象?nbsp;wait() Ҏ而阻塞的所有线E一ơ性全部解除阻塞。当Ӟ只有获得锁的那一个线E才能进入可执行状态?br /> <br /> <br /> <br /> 谈到dQ就不能不谈一谈死锁,略一分析p发现Qsuspend() Ҏ和不指定时期限?nbsp;wait() Ҏ的调用都可能产生死锁。遗憄是,Java q不在语aU别上支持死锁的避免Q我们在~程中必d心地避免死锁?br /> <br /> <br /> <br /> 以上我们?nbsp;Java 中实现线E阻塞的各种Ҏ作了一番分析,我们重点分析?nbsp;wait() ?nbsp;notify() ҎQ因为它们的功能最强大Q用也最灉|Q但是这也导致了它们的效率较低,较容易出错。实际用中我们应该灉|使用各种ҎQ以便更好地辑ֈ我们的目的?br /> <br /> <br /> <br /> <strong>七:守护U程</strong><br /> <br /> <br /> <br /> 守护U程是一cȝD的U程Q它和普通线E的区别在于它ƈ不是应用E序的核心部分,当一个应用程序的所有非守护U程l止q行Ӟ即仍然有守护线E在q行Q应用程序也终止,反之Q只要有一个非守护U程在运行,应用E序׃会终止。守护线E一般被用于在后Cؓ其它U程提供服务?br /> <br /> <br /> 可以通过调用Ҏ isDaemon() 来判断一个线E是否是守护U程Q也可以调用Ҏ setDaemon() 来将一个线E设为守护线E?br /> <br /> <br /> <br /> <strong>八:U程l?/strong><br /> <br /> <br /> <br /> U程l是一?nbsp;Java Ҏ的概念,?nbsp;Java 中,U程l是cThreadGroup 的对象,每个U程都隶属于唯一一个线E组Q这个线E组在线E创建时指定q在U程的整个生命期内都不能更改。你可以通过调用包含 ThreadGroup cd参数?nbsp;Thread cL造函数来指定U程属的U程l,若没有指定,则线E缺省地隶属于名?nbsp;system 的系l线E组?br /> <br /> <br /> ?nbsp;Java 中,除了预徏的系l线E组外,所有线E组都必L式创建?br /> <br /> <br /> <br /> ?nbsp;Java 中,除系l线E组外的每个U程l又隶属于另一个线E组Q你可以在创建线E组时指定其所隶属的线E组Q若没有指定Q则~省地隶属于pȝU程l。这P所有线E组l成了一以pȝU程lؓ根的树?br /> <br /> <br /> Java 允许我们对一个线E组中的所有线E同时进行操作,比如我们可以通过调用U程l的相应Ҏ来设|其中所有线E的优先U,也可以启动或d其中的所有线E?br /> <br /> <br /> <br /> Java 的线E组机制的另一个重要作用是U程安全。线E组机制允许我们通过分组来区分有不同安全Ҏ的U程Q对不同l的U程q行不同的处理,q可以通过U程l的分层l构来支持不对等安全措施的采用。Java ?nbsp;ThreadGroup cL供了大量的方法来方便我们对线E组树中的每一个线E组以及U程l中的每一个线E进行操作?br /> <br /> <br /> <br /> <strong>九:ȝ</strong><br /> <br /> <br /> <br /> 在这一讲中Q我们一起学习了 Java 多线E编E的Ҏ面面Q包括创建线E,以及对多个线E进行调度、管理。我们深刻认识到了多U程~程的复杂性,以及U程切换开销带来的多U程E序的低效性,q也促我们认真地思考一个问题:我们是否需要多U程Q何旉要多U程Q?br /> <br /> <br /> 多线E的核心在于多个代码块ƈ发执行,本质特点在于各代码块之间的代码是乱序执行的。我们的E序是否需要多U程Q就是要看这是否也是它的内在特点?br /> <br /> <br /> <br /> 假如我们的程序根本不要求多个代码块ƈ发执行,那自然不需要用多U程Q假如我们的E序虽然要求多个代码块ƈ发执行,但是却不要求乱序Q则我们完全可以用一个@环来单高效地实现Q也不需要用多U程Q只有当它完全符合多U程的特ҎQ多U程机制对线E间通信和线E管理的强大支持才能有用武之圎ͼq时使用多线E才是值得的?nbsp;</p> <img src ="http://www.tkk7.com/AntiquMan/aggbug/263016.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.tkk7.com/AntiquMan/" target="_blank">AntiquMan</a> 2009-03-31 01:15 <a href="http://www.tkk7.com/AntiquMan/archive/2009/03/31/263016.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item></channel></rss> <footer> <div class="friendship-link"> <p>лǵվܻԴȤ</p> <a href="http://www.tkk7.com/" title="亚洲av成人片在线观看">亚洲av成人片在线观看</a> <div class="friend-links"> </div> </div> </footer> վ֩ģ壺 <a href="http://as5566.com" target="_blank">ձƷѴȫ</a>| <a href="http://tv695.com" target="_blank">99re6ƵƷ</a>| <a href="http://ksdhao.com" target="_blank">aĻ</a>| <a href="http://dgyinhezy.com" target="_blank">޳˵Ӱվ</a>| <a href="http://cqtjqcc.com" target="_blank">ɫͼۺվ</a>| <a href="http://686kp.com" target="_blank">˳վձƬ</a>| <a href="http://kj555888.com" target="_blank">һëƬѿ</a>| <a href="http://qixiresort.com" target="_blank">ڳ߿</a>| <a href="http://xuanboart.com" target="_blank">Ʒ޾Ʒ</a>| <a href="http://45-po.com" target="_blank">ձߵӰ</a>| <a href="http://bearsou.com" target="_blank">޹ƷþþžŴƬ</a>| <a href="http://0755haoma.com" target="_blank">˳ŷĻ</a>| <a href="http://yuntuzy.com" target="_blank">޳av޳av</a>| <a href="http://mcsser.com" target="_blank">avרavëƬ</a>| <a href="http://qianmiu.com" target="_blank">v߹ۿ</a>| <a href="http://27simnjingmiguan.com" target="_blank">һëƬѲ</a>| <a href="http://zjszbwzl.com" target="_blank">ĻƬa</a>| <a href="http://bet06966.com" target="_blank">ձ˳ƵѲ</a>| <a href="http://ccccccx.com" target="_blank">99þþùƷţţĴ </a>| <a href="http://400209.com" target="_blank">þþƷĻ鶹</a>| <a href="http://www137av.com" target="_blank">Ƶһ</a>| <a href="http://nxeea.com" target="_blank">ۺɫ</a>| <a href="http://www66913.com" target="_blank">˾Ʒձר6</a>| <a href="http://w6446.com" target="_blank">޺ݺۺϾþ</a>| <a href="http://wwwhaole10.com" target="_blank">ڵ߳Ƶѹۿ</a>| <a href="http://xass1.com" target="_blank">˳Ƶ߲Ų</a>| <a href="http://hnkangshi.com" target="_blank">Ʒһ</a>| <a href="http://44od.com" target="_blank">1000ڵƵۿ</a>| <a href="http://jnyygs.com" target="_blank">޾ƷѶ</a>| <a href="http://517qq.com" target="_blank">ts߹ۿƵ</a>| <a href="http://fsbj168.com" target="_blank">ݺ޺ݺŷ2019</a>| <a href="http://taobaohuopin.com" target="_blank">޵һվ</a>| <a href="http://guilinsix.com" target="_blank">޴ɫAvר</a>| <a href="http://siqingsizu.com" target="_blank">Ʒһֱ</a>| <a href="http://k96d.com" target="_blank">ˮƵwwwƵ</a>| <a href="http://xass1.com" target="_blank">Ļ</a>| <a href="http://klno1.com" target="_blank">պһëƬ</a>| <a href="http://57az.com" target="_blank">͵v͵v޸</a>| <a href="http://yisousou.com" target="_blank">޹һ߹ۿ</a>| <a href="http://saozib.com" target="_blank">ɫһƵ</a>| <a href="http://1992zyzp.com" target="_blank">2019ĻѴȫ5</a>| <script> (function(){ var bp = document.createElement('script'); var curProtocol = window.location.protocol.split(':')[0]; if (curProtocol === 'https') { bp.src = 'https://zz.bdstatic.com/linksubmit/push.js'; } else { bp.src = 'http://push.zhanzhang.baidu.com/push.js'; } var s = document.getElementsByTagName("script")[0]; s.parentNode.insertBefore(bp, s); })(); </script> </body>