黑马程序员java学习日记六 线程的学习总结

线程的定义 ,概念

进程:是一个正在执行的程序.

       每一个进行执行都有一个执行顺序,该顺序是一个执行路径,或叫一个控制单元.

线程:就是进程中的一个独立控制单元.

       线程在控制着进行的执行.

一个进程中至少有一个线程.

java VM启动的时候会有一个进程叫java.exe.

该进程中至少有一个线程在负责java程序的执行.而且这个线程运行的代码存在于main方法中,该线程称之为主线程.

扩展:其实更细节说明jvm,jvm启动不止一个线程,还有负责垃圾回收机制的线程.

如何在自定义代码中,自定义一个线程呢?

通过对api的查找,java已经提供了对线程这类事物的描述,就是Tread

创建线程的第一种方式:继承Thread.

步骤:

1.继承Thread.

2.复写Thread类中的run方法.

    目的:将自定义代码存储在run方法中,让线程运行.

3.创建该子类的对象,并调用线程的start方法.

该方法有两个作用:启动线程,调用run方法.

创建线程的第二种方式:实现Runnable接口

步骤:

1.定义类实现Runnable接口

2.覆盖Runnable接口中的run方法.

    将线程要运行的代码存放在该run方法中.

3.通过Thread类建立线程对象.

4.Runnable解救的子类对象作为实际参数传递给Thread类的构造函数.

     为什么要将Runnable接口的子类对象传递给Thread的构造函数.

     因为,自定义的run方法所属的对象是Runnable接口的子类对象.

     所以要让线程去指定指定对象的run方法,就必须明确该run方法所属对象.

5.调用Thread类的start方法开启线程并调用Runnable接口子类的方法.

实现方式和继承方式有什么区别呢?

实现方式好处:避免了单继承的局限性.

在定义线程时,建议使用实现Runnable的方式.

两种方式的区别:

继承Thread:线程代码存放在Thread子类的run方法中.

实现Runnable:线程代码存放在接口子类的run方法中

发现运行结果每一次都不同.

因为多个线程都在获取cpu执行权,cpu执行到谁,谁就运行.

明确一点,在某一时刻,只能有一个程序在运行.(多核除外)

cpu在做着快速的切换,以达到看上去是同时运行的效果.

毕老师总结:

我们可以形象的把多线程的运行行为看做线程在互相抢夺cpu的执行权.

值就是多线程的一个特性:随机性.谁抢到谁执行,至于执行多长,cpu说的算.

为什么要覆盖run方法呢?

Thread类用于描述线程.

该类就定义了一个功能,用于存储线程要运行的代码.该存储功能就是run方法.

也就是Thread类中的run方法,是用于存储线程要运行的代码.

举例代码:

[java]  view plain copy
  1. class Demo extends Thread  
  2. {  
  3.      public void run()  
  4.      {  
  5.           for (int x=0;x<60;x++)  
  6.           {  
  7.                System.out.println("Demo run--"+x);  
  8.           }  
  9.      }  
  10. }  
  11. class  ThreadDemo  
  12. {  
  13.      public static void main(String[] args)  
  14.      {  
  15.           Demo d = new Demo();  
  16.           d.start();//开启线程,并执行该线程的run方法.  
  17.           //d.run();//没调用线程,直接调用了run方法  
  18.           for (int x=0;x<60;x++)  
  19.           {  
  20.                System.out.println("Hello World--"+x);  
  21.           }           
  22.      }  
  23. }  

获取线程名称以及对象:

创建两个线程,和主线程交替运行.

原来线程都有自己的默认名称

Thread-编号,该编号从0开始.

Thread.currentThread():获取当前线程对象.

getName():获取线程名称.

设置线程名称:setName或者构造函数.

局部变量在每一个线程中都有独立的内存空间.

[java]  view plain copy
  1. class DemoA extends Thread  
  2. {  
  3.      //private String name;  
  4.      DemoA(String name)  
  5.      {  
  6.           super(name);  
  7.           //this.name=name;  
  8.      }  
  9.      public void run()  
  10.      {  
  11.           for (int x = 0;x<10;x++)  
  12.           {  
  13.                System.out.println((Thread.currentThread()==this)+this.getName()+"-run-"+x);  
  14.           }  
  15.      }  
  16. }  
  17. class ThreadTest  
  18. {  
  19.      public static void main(String[] args)  
  20.      {  
  21.           new Thread().getName();  
  22.           DemoA d1 = new DemoA("one---");  
  23.           d1.start();  
  24.           DemoA d2 = new DemoA("two+++");  
  25.           d2.start();  
  26.           for (int x = 0;x<10;x++)  
  27.           {  
  28.                System.out.println("three==="+x+x);  
  29.           }  
  30.      }  
  31. }  
多窗口售票练习

[java]  view plain copy
  1. class Ticket implements Runnable  
  2. {  
  3.      private int ticket = 20;  
  4.      public void run()  
  5.      {  
  6.           while(ticket>0)  
  7.           {  
  8.                System.out.println(Thread.currentThread().getName()+"---"+ticket--);  
  9.           }  
  10.      }  
  11. }  
  12.   
  13. class  TicketDemo  
  14. {  
  15.      public static void main(String[] args)  
  16.      {  
  17.           Ticket t = new Ticket();;  
  18.         new Thread(t).start();  
  19.         new Thread(t).start();  
  20.         new Thread(t).start();  
  21.         new Thread(t).start();  
  22.      }  
  23. }  
通过运行上面的多窗口售票练习出现了0,-1,-2等错票,该问题就引出了下面的知识点.

多线程的安全问题--同步代码块

多线程的运行出现了安全问题.

问题的原因:

    当多条语句在操作同一个线程共享数据时.一个线程对多条语句只执行一部分,还没有执行完.

     另一个线程参与进来执行.导致共享数据的错误.

解决办法:

    对多条操作共享数据的语句,只能让一个线程都执行完.在执行过程中,其他线程不可以参与执行.

java对于多线程的安全问题提供了专业的解决方式.

就是同步代码块.

synchronized(对象())

{

   需要被同步的代码

}

对象如同锁,持有锁的线程可以再同步中执行.

没有持有锁的线程,即使获取了cpu的执行权,也进不去,因为没有锁.

毕老师说synchronized就如同火车上的卫生间---经典

同步的前提!!!!!

1.必须要有两个或两个以上的线程.

2.必须是多个线程使用同一个锁.

必须保证同步中只能有一个线程运行.

好处:解决了多线程的安全问题.

弊端:多个线程需要判断锁,较为消耗资源.

多窗口售票练习的修改版:

[java]  view plain copy
  1. class Ticket implements Runnable  
  2. {  
  3.      private int ticket = 1000;  
  4.      Object obj = new Object();  
  5.      public void run()  
  6.      {  
  7.           while(true)  
  8.           {  
  9.                synchronized(obj)\\obj代表任意对象  
  10.                {  
  11.                     if(ticket>0)  
  12.                     {  
  13.                          try{Thread.sleep(10);}catch(Exception e){}  
  14.                          System.out.println(Thread.currentThread().getName()+"---"+ticket--);  
  15.                     }  
  16.                }  
  17.           }  
  18.      }  
  19. }  
  20.   
  21. class  TicketDemo1  
  22. {  
  23.      public static void main(String[] args)  
  24.      {  
  25.           Ticket t = new Ticket();;  
  26.         new Thread(t).start();  
  27.         new Thread(t).start();  
  28.         new Thread(t).start();  
  29.         new Thread(t).start();  
  30.      }  
  31. }  

同步函数:同步代码块可以抽取为同步函数,以简化书写.

同步函数用的那一个锁呢?

函数需要被对象调用.函数都有一个所属对象的引用this

所以同步函数使用的锁是this.

通过该程序进行验证.

使用两个线程来卖票.

一个线程在同步代码块中.

一个线程在同步函数中.

都在执行卖票动作.

见下面代码:

[java]  view plain copy
  1. class Ticket implements Runnable  
  2. {  
  3.      private int ticket = 200;  
  4.      //Object obj = new Object();  
  5.      boolean flag = true;  
  6.      public void run()  
  7.      {  
  8.           if(flag)  
  9.           {  
  10.                while(true)  
  11.                {  
  12.                     synchronized(this)  
  13.                     {  
  14.                          if(ticket>0)  
  15.                          {  
  16.                               try{Thread.sleep(10);}catch(Exception e){}  
  17.                               System.out.println(Thread.currentThread().getName()+"---code---"+ticket--);  
  18.                          }  
  19.                     }  
  20.                }  
  21.           }  
  22.           else  
  23.                while(true)  
  24.                {  
  25.                     show();  
  26.                }  
  27.      }  
  28.      public synchronized void show()  
  29.      {  
  30.           if(ticket>0)  
  31.           {  
  32.                try{Thread.sleep(10);}catch(Exception e){}  
  33.                System.out.println(Thread.currentThread().getName()+"--show--"+ticket--);  
  34.           }  
  35.      }  
  36. }  
  37.   
  38. class  ThisLockDemo  
  39. {  
  40.      public static void main(String[] args)  
  41.      {  
  42.           Ticket t = new Ticket();;  
  43.         new Thread(t).start();  
  44.           try{Thread.sleep(10);}catch(Exception e){}  
  45.           t.flag = false;  
  46.         new Thread(t).start();  
  47.      }  
  48. }  

如果同步函数被静态修饰后,使用的锁是什么呢?

通过验证,发现不再是this,因为静态方法中也不可以引用this.

静态进内存是,内存中没有本类对象,但是一定有该类对应的字节码文件对象.

类名.class,该了对象类型是Class.

静态的同步方法,使用的锁是该方法所在的字节码文件对象.类名.class

[java]  view plain copy
  1. class Ticket implements Runnable  
  2. {  
  3.      private static int ticket = 200;  
  4.      //Object obj = new Object();  
  5.      boolean flag = true;  
  6.      public void run()  
  7.      {  
  8.           if(flag)  
  9.           {  
  10.                while(true)  
  11.                {  
  12.                     synchronized(Ticket.class)  
  13.                     {  
  14.                          if(ticket>0)  
  15.                          {  
  16.                               try{Thread.sleep(10);}catch(Exception e){}  
  17.                               System.out.println(Thread.currentThread().getName()+"---code---"+ticket--);  
  18.                          }  
  19.                     }  
  20.                }  
  21.           }  
  22.           else  
  23.                while(true)  
  24.                {  
  25.                     show();  
  26.                }  
  27.      }  
  28.      public static synchronized void show()  
  29.      {  
  30.           if(ticket>0)  
  31.           {  
  32.                try{Thread.sleep(10);}catch(Exception e){}  
  33.                System.out.println(Thread.currentThread().getName()+"--show--"+ticket--);  
  34.           }  
  35.      }  
  36. }  
  37.   
  38. class  StaticLockDemo  
  39. {  
  40.      public static void main(String[] args)  
  41.      {  
  42.           Ticket t = new Ticket();;  
  43.         new Thread(t).start();  
  44.           try{Thread.sleep(10);}catch(Exception e){}  
  45.           t.flag = false;  
  46.         new Thread(t).start();  
  47.      }  
  48. }  

同步的死锁问题:

死锁:2个或2个以上的进程在执行过程中,因为争夺资源而造成的一种互相等待的现象,若无外力作用,他们都无法推进下去,此时系统处于死锁状态,这些永远在互相等待的进程成为死锁进程。

产生原因:同步中嵌套同步,而锁不同;

线程之间的通信

其实就是多个线程在操作同一个资源,

但是操作的动作不同.

wait();

notify();

notifyAll();

都使用在synchronized同步中,因为要对持有监视器()的线程操作.

所以要使用在同步中,因为只有同步才具有监视器().

为什么这些操作线程的方法要定义在Object类中呢?

因为这些方法在操作同步中线程时,都必须要标识它们所操作的线程持有的锁.

只有同一个锁上的被等待线程,可以被同一个锁上的notify唤醒.

不可以对不同锁中的线程进行唤醒.

也就是说,等待和唤醒必须是同一个锁.

而锁可以是任意对象,所以可以被任意对象调用的方法定义在Object类中.

举例代码:

[java]  view plain copy
  1. //输入输出类的共享资源  
  2. class Share  
  3. {  
  4.      String name;  
  5.      String sex;  
  6.     boolean flag = false;  
  7.     //供输入调用的方法  
  8.      public synchronized void set(String name,String sex)  
  9.      {  
  10.           if (flag)  
  11.                try{this.wait();}catch(Exception e){}  
  12.           this.name = name;  
  13.           this .sex = sex;  
  14.           flag = true;  
  15.           this.notify();  
  16.      }  
  17.      //供输出调用的方法  
  18.      public synchronized void print()  
  19.      {  
  20.           if (!flag)  
  21.                try{this.wait();}catch(Exception e){}  
  22.          System.out.println(Thread.currentThread().getName()+name+"----"+sex);  
  23.           flag = false;  
  24.           this.notify();  
  25.      }  
  26. }  
  27. class InPut implements Runnable  
  28. {  
  29.     Share s;  
  30.      int x = 0;  
  31.      InPut(Share s)  
  32.      {  
  33.           this.s = s;  
  34.      }  
  35.      public void run()  
  36.      {  
  37.           inMethod();  
  38.      }  
  39.      public void inMethod()  
  40.      {  
  41.           while (true)  
  42.           {  
  43.                     if(x==0)  
  44.                          s.set("toby","man") ;  
  45.                     else  
  46.                          s.set("肖华","女女女女") ;  
  47.                     x = (x+1)%2;  
  48.           }  
  49.      }  
  50. }  
  51. class OutPut implements Runnable  
  52. {  
  53.      Share s;  
  54.      OutPut(Share s)  
  55.      {  
  56.           this.s = s;  
  57.      }  
  58.   
  59.      public void run()  
  60.      {  
  61.           outMethod();  
  62.      }  
  63.      public void outMethod()  
  64.      {  
  65.           while (true)  
  66.           {  
  67.                s.print();  
  68.           }  
  69.      }  
  70. }  
  71.   
  72. class  DuoDemo  
  73. {  
  74.      public static void main(String[] args)  
  75.      {  
  76.           Share s = new Share();  
  77.           InPut i = new InPut(s);  
  78.           OutPut o = new OutPut(s);  
  79.           new Thread(i).start();  
  80.           new Thread(o).start();  
  81.      }  
  82. }  
线程间通信--生产者消费者练习.

[java]  view plain copy
  1. //生产者和消费者的共享资源类  
  2. class Resource  
  3. {  
  4.      private String name;  
  5.      private int count = 1;  
  6.      //定义一个boolean型的标记变量;  
  7.      boolean flag = false;  
  8.      public synchronized void set(String name)  
  9.      {  
  10.           while (flag)  
  11.                try{wait();}catch(Exception e){}  
  12.           this.name = name + count++;  
  13.           System.out.println(Thread.currentThread().getName()+"----生产者----"+this.name);  
  14.           flag = true;  
  15.           this.notifyAll();  
  16.      }  
  17.      public synchronized void get()  
  18.      {  
  19.           while (!flag)  
  20.                try{wait();}catch(Exception e){}  
  21.           System.out.println(Thread.currentThread().getName()+"消费者"+this.name);  
  22.           flag = false;  
  23.           this.notifyAll();  
  24.      }  
  25. }  
  26. class Pro implements Runnable  
  27. {  
  28.     Resource r;  
  29.      Pro(Resource r)  
  30.      {  
  31.           this.r = r;  
  32.      }  
  33.      public void run()  
  34.     {  
  35.           while (true)  
  36.                r.set("商品");  
  37.      }  
  38. }  
  39. class Conn implements Runnable  
  40. {  
  41.     Resource r;  
  42.      Conn(Resource r)  
  43.      {  
  44.           this.r = r;  
  45.      }  
  46.      public void run()  
  47.     {  
  48.           while (true)  
  49.                r.get();  
  50.      }  
  51. }  
  52. class ProConDemo1  
  53. {  
  54.      public static void main(String[] args)  
  55.      {  
  56.           Resource s = new Resource();  
  57.           new Thread(new Pro(s)).start();//0  
  58.           new Thread(new Conn(s)).start();//1  
  59.           new Thread(new Pro(s)).start();//2  
  60.           new Thread(new Conn(s)).start();//3  
  61.      }  
  62. }  
线程间通信--生产者消费者练习jdk1.5升级版
[java]  view plain copy
  1. //导入jdk1.5版的lock类  
  2. import java.util.concurrent.locks.*;  
  3. //定义一个生产者消费者共享资源类  
  4. class Resource  
  5. {  
  6.      private String name;  
  7.      private int count = 1;  
  8.      boolean flag = false;  
  9.      //定义一个锁  
  10.      Lock l = new ReentrantLock();  
  11.      //定义2个锁的对象  
  12.      Condition conset = l.newCondition();  
  13.      Condition conout = l.newCondition();  
  14.      public void set(String name)throws InterruptedException  
  15.      {  
  16.           l.lock ();//取代synchronized  
  17.           try  
  18.           {  
  19.                if(flag)  
  20.                     conset.await();//取代wait  
  21.                this.name = name + count++;  
  22.                System.out.println(Thread.currentThread().getName()+"_____生产者____"+this.name);  
  23.                flag = true;  
  24.                conout.signal();//取代notify,唤醒调用out方法的线程  
  25.           }  
  26.           finally  
  27.           {  
  28.                l.unlock();//取代synchronized  
  29.           }  
  30.      }  
  31.      public void out()throws InterruptedException  
  32.      {  
  33.           l.lock ();  
  34.           try  
  35.           {  
  36.                if(!flag)  
  37.                     conout.await();  
  38.                System.out.println(Thread.currentThread().getName()+"消费者"+this.name);  
  39.                flag = false;  
  40.                conset.signal();//唤醒调用set方法的线程  
  41.           }  
  42.           finally  
  43.           {  
  44.                l.unlock();                
  45.           }  
  46.      }  
  47. }  
  48. class Pro implements Runnable  
  49. {  
  50.      Resource r;  
  51.      Pro(Resource r)  
  52.      {  
  53.           this.r = r;  
  54.      }  
  55.      public void run()  
  56.      {  
  57.           while (true)  
  58.                try  
  59.                {  
  60.                     r.set("商品");  
  61.                }  
  62.                catch (InterruptedException i)  
  63.                {  
  64.                     System.out.println("呵呵");  
  65.                }  
  66.      }  
  67. }  
  68. class Conn implements Runnable  
  69. {  
  70.      Resource r;  
  71.      Conn(Resource r)  
  72.      {  
  73.           this.r = r;  
  74.      }  
  75.      public void run()  
  76.      {  
  77.           while (true)  
  78.                try  
  79.                {  
  80.                     r.out();  
  81.                }  
  82.                catch (InterruptedException i)  
  83.                {  
  84.                     System.out.println("呵呵");  
  85.                }  
  86.      }  
  87. }  
  88. class ProConDemo2  
  89. {  
  90.      public static void main(String[] args)  
  91.      {  
  92.           Resource r = new Resource();  
  93.           Pro p = new Pro(r);  
  94.           Conn c = new Conn(r);  
  95.           new Thread(p).start();  
  96.           new Thread(p).start();  
  97.           new Thread(c).start();  
  98.           new Thread(c).start();  
  99.      }  
  100. }  

如何停止线程?

只有一种,run方法结束.

开启多线程运行,运行代码通常是循环结构.

只要控制住循环,就可以让run方法结束,也就是线程结束.

特殊情况:

当线程处于冻结状态.

就不会读取到标记.那么线程就不会结束.

当没有指定的方式让冻结的线程恢复到运行状态时,这时需要对冻结进行清除.

强制让线程恢复到运行状态中来,这样就可以操作标记让线程结束.

Thread类中提供了该方法 interrupt();

举例代码:

[java]  view plain copy
  1. class StopThread implements Runnable  
  2. {  
  3.      boolean flag = true;  
  4.      public synchronized void run()  
  5.      {  
  6.           while(flag)  
  7.           {  
  8.                try  
  9.                {  
  10.                     wait();  
  11.                }  
  12.                catch (InterruptedException i)  
  13.                {  
  14.                     System.out.println(Thread.currentThread().getName()+"---Exception!");  
  15.                     flag = false;  
  16.                }  
  17.                System.out.println(Thread.currentThread().getName()+"---stop");  
  18.           }  
  19.      }  
  20.      public void changeFlag()  
  21.      {  
  22.           flag = false;  
  23.      }  
  24. }  
  25. class StopThreadDemo  
  26. {  
  27.      public static void main(String[] args)  
  28.      {  
  29.           StopThread st = new StopThread();  
  30.           Thread t1 = new Thread(st);  
  31.           Thread t2 = new Thread(st);  
  32.           t1.start();  
  33.           t2.start();  
  34.   
  35.           int num = 0;  
  36.           while (true)  
  37.           {  
  38.                if(num++ == 60)  
  39.                {  
  40.                     //st.changeFlag();  
  41.                     t1.interrupt();  
  42.                     t2.interrupt();  
  43.                     break;  
  44.                }  
  45.                System.out.println(Thread.currentThread().getName()+"---"+num);  
  46.           }           
  47.           System.out.println(Thread.currentThread().getName()+"---over");  
  48.      }  
  49. }  

守护线程(后台线程)

Thread类中的setDaemon(boolean on)方法.

on如果为true,则将该线程标记为守护线程(后台线程).

将该线程标记为守护线程或用户线程.当正在运行的线程都是守护线程时,Java 虚拟机退出.

该方法必须在启动线程前调用.

这可能抛出 SecurityException(在当前线程中).

join方法

A线程执行到了B线程的join()方法时,A线程就会等待.B线程都执行完,A才会执行.

join可以用来临时加入线程执行.

举例代码:

[java]  view plain copy
  1. class Demo implements Runnable  
  2. {  
  3.      public void run()  
  4.      {  
  5.           for(int x=0; x<70; x++)  
  6.           {  
  7.                System.out.println(Thread.currentThread().getName()+"....."+x);  
  8.           }  
  9.      }  
  10. }  
  11. class JoinDemo  
  12. {  
  13.      public static void main(String[] args)throws Exception  
  14.      {  
  15.           Demo d = new Demo();  
  16.           Thread t1 = new Thread(d);  
  17.           Thread t2 = new Thread(d);  
  18.           t1.start();  
  19.           t2.start();  
  20.           t1.join();//等待t1终止  
  21.           for (int x=0; x<80; x++ )  
  22.           {  
  23.                System.out.println("main....."+x);  
  24.           }  
  25.   
  26.           System.out.println("over");  
  27.      }  
  28. }  

优先级和yield方法

yield()方法称为“退让”,它把运行机会让给了同等级的其他线程.

yield()只是使当前线程重新回到可执行状态,所有执行yield()的线程有可能在进入到

可执行状态后马上又被执行,所以yield()方法只能使同优先级的线程有执行的机会.

例子:

[java]  view plain copy
  1. class Demo implements Runnable  
  2. {  
  3.      public void run()  
  4.      {  
  5.           for(int x=0; x<70; x++)  
  6.           {  
  7.                System.out.println(Thread.currentThread().toString()+"....."+x);  
  8.                Thread.yield();//调用Thread的yield方法  
  9.           }  
  10.      }  
  11. }  
  12. class PriorityYieldDemo  
  13. {  
  14.      public static void main(String[] args)throws Exception  
  15.      {  
  16.           Demo d = new Demo();  
  17.           Thread t1 = new Thread(d);  
  18.           Thread t2 = new Thread(d);  
  19.           t1.start();  
  20.           //给t1线程命名为haha  
  21.           t1.setName("haha");  
  22.           //设置t1线程的优先级为最高级10,最低级为MIN_PRIORITY,中间为NORM_PRIORITY.  
  23.           t1.setPriority(Thread.MAX_PRIORITY);  
  24.           t2.start();  
  25.           for (int x=0; x<80; x++ )  
  26.           {  
  27.                System.out.println("main....."+x);  
  28.           }  
  29.   
  30.           System.out.println("over");  
  31.      }  
  32. }  

java之yield(),sleep(),join()区别详解

1sleep()

使当前线程(即调用该方法的线程)暂停执行一段时间,让其他线程有机会继续执行,但它并不释放对象锁。也就是说如果有synchronized同步快,其他线程仍然不能访问共享数据。注意该方法要捕捉异常。

例如有两个线程同时执行(没有synchronized)一个线程优先级为MAX_PRIORITY,另一个为MIN_PRIORITY,如果没有Sleep()方法,只有高优先级的线程执行完毕后,低优先级的线程才能够执行;但是高优先级的线程sleep(500)后,低优先级就有机会执行了。

总之,sleep()可以使低优先级的线程得到执行的机会,当然也可以让同优先级、高优先级的线程有执行的机会。

!!Thread.sleep(long millis)必须带有一个时间参数。

2join()

join()方法使调用该方法的线程在此之前执行完毕,也就是等待该方法的线程执行完毕后再往下继续执行。注意该方法也需要捕捉异常。

 

3yield()

该方法与sleep()类似,只是不能由用户指定暂停多长时间,并且yield()方法只能让同优先级的线程有执行的机会。

yield()方法称为“退让”,它把运行机会让给了同等级的其他线程。

yield()只是使当前线程重新回到可执行状态,所有执行yield()的线程有可能在进入到可执行状态后马上又被执行,所以yield()方法只能使同优先级的线程有执行的机会。

!!yield()没有参数.


多线程--线程的匿名内部类写法

[java]  view plain copy
  1. class ThreadTest  
  2. {  
  3.      public static void main(String[] args)  
  4.      {  
  5.           new Thread()  
  6.           {  
  7.                public void run()  
  8.                {  
  9.                     for (int x=0; x<30; x++)  
  10.                     {  
  11.                          System.out.println(Thread.currentThread().toString()+"..."+x);  
  12.                     }  
  13.                }  
  14.           }.start();  
  15.   
  16.           new Thread(new Runnable()  
  17.           {  
  18.                public void run()  
  19.                {  
  20.                     for (int x=0; x<30; x++)  
  21.                     {  
  22.                          System.out.println(Thread.currentThread().toString()+"..."+x);  
  23.                     }  
  24.                }  
  25.           }).start();           
  26.   
  27.           for (int x=0; x<30; x++)  
  28.           {  
  29.                System.out.println(Thread.currentThread().toString()+"..."+x);  
  30.           }  
  31.      }  
  32. }  

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值