标签:
1.1、线程之间的通信方法
多个线程在处理统一资源,但是任务却不同,这时候就需要线程间通信。
等待/唤醒机制涉及的方法:
1. wait():让线程处于冻结状态,被wait的线程会被存储到线程池中。
2. notify():唤醒线程池中的一个线程(任何一个都有可能)。
3. notifyAll():唤醒线程池中的所有线程。
备注
1、这些方法都必须定义在同步中,因为这些方法是用于操作线程状态的方法。
2、必须要明确到底操作的是哪个锁上的线程!
3、wait和sleep区别?
1)wait可以指定时间也可以不指定。sleep必须指定时间。
2)在同步中时,对CPU的执行权和锁的处理不同。
wait:释放执行权,释放锁。
sleep:释放执行权,不释放锁。
为什么操作线程的方法wait、notify、notifyAll定义在了object类中,因为这些方法是监视器的方法,监视器其实就是锁。
锁可以是任意的对象,任意的对象调用的方式一定在object类中。
1.2、两个线程交替打印1-100
package com.pb.thread.demo1; public class Demo { private int num=1; /* * 打印偶数 */ public synchronized void put(){ if(num%2==0){ try { wait(); } catch (InterruptedException e) { e.printStackTrace(); } } notify(); System.out.println(Thread.currentThread().getName()+","+num); num++; } /* * 打印奇数 */ public synchronized void get(){ if(num%2!=0){ try { //当前线程等待 wait(); } catch (InterruptedException e) { e.printStackTrace(); } } //唤醒另一等待中的线程 notify(); System.out.println(Thread.currentThread().getName()+","+num); num++; } public int getNum() { return num; } public void setNum(int num) { this.num = num; } }
package com.pb.thread.demo1; /** * 打印偶数 * @author denny * */ public class A implements Runnable { Demo demo; public A(Demo demo){ this.demo=demo; } @Override public void run() { while(demo.getNum()<100){ demo.put(); } } } package com.pb.thread.demo1; /** * 打印奇数 * @author denny * */ public class B implements Runnable { Demo demo; public B(Demo demo) { this.demo = demo; } @Override public void run() { while(demo.getNum()<100){ demo.get(); } } }
测试类
package com.pb.thread.demo1; /** * 2个线程交替打印1-100 * @author denny * */ public class Test { public static void main(String[] args) { Demo demo=new Demo(); A a=new A(demo); B b=new B(demo); Thread t1=new Thread(a); Thread t2=new Thread(b); t1.start(); t2.start(); } }
结果:
Picked up JAVA_TOOL_OPTIONS: -javaagent:/usr/share/java/jayatanaag.jar Thread-0,1 Thread-1,2 Thread-0,3 Thread-1,4 Thread-0,5 Thread-1,6 Thread-0,7 Thread-1,8 Thread-0,9 Thread-1,10 Thread-0,11 Thread-1,12 Thread-0,13 Thread-1,14 Thread-0,15 Thread-1,16 Thread-0,17 Thread-1,18 Thread-0,19 Thread-1,20 Thread-0,21 Thread-1,22 Thread-0,23 Thread-1,24 Thread-0,25 Thread-1,26 Thread-0,27 Thread-1,28 Thread-0,29 Thread-1,30 Thread-0,31 Thread-1,32 Thread-0,33 Thread-1,34 Thread-0,35 Thread-1,36 Thread-0,37 Thread-1,38 Thread-0,39 Thread-1,40 Thread-0,41 Thread-1,42 Thread-0,43 Thread-1,44 Thread-0,45 Thread-1,46 Thread-0,47 Thread-1,48 Thread-0,49 Thread-1,50 Thread-0,51 Thread-1,52 Thread-0,53 Thread-1,54 Thread-0,55 Thread-1,56 Thread-0,57 Thread-1,58 Thread-0,59 Thread-1,60 Thread-0,61 Thread-1,62 Thread-0,63 Thread-1,64 Thread-0,65 Thread-1,66 Thread-0,67 Thread-1,68 Thread-0,69 Thread-1,70 Thread-0,71 Thread-1,72 Thread-0,73 Thread-1,74 Thread-0,75 Thread-1,76 Thread-0,77 Thread-1,78 Thread-0,79 Thread-1,80 Thread-0,81 Thread-1,82 Thread-0,83 Thread-1,84 Thread-0,85 Thread-1,86 Thread-0,87 Thread-1,88 Thread-0,89 Thread-1,90 Thread-0,91 Thread-1,92 Thread-0,93 Thread-1,94 Thread-0,95 Thread-1,96 Thread-0,97 Thread-1,98 Thread-0,99 Thread-1,100
交替打印
一个输入,一个输出
package com.pb.thread.demo3; /** * * @author Denny * 线程间通讯: * 其它就是多个线程在操作同一个资源 * 只是操作的动作不同 * */ public class Person { private String name; private int age; private String gender; private boolean flag=false; public String getName() { return name; } public void setName(String name) { this.name = name; } public int getAge() { return age; } public void setAge(int age) { this.age = age; } public String getGender() { return gender; } public void setGender(String gender) { this.gender = gender; } public boolean getFlag() { return flag; } public void setFlag(boolean flag) { this.flag = flag; } } //====================== package com.pb.thread.demo3; public class Input implements Runnable { private Person person; public Input(Person person) { this.person = person; } @Override public void run() { int x = 0; while (true) { synchronized (person) { if (person.getFlag()) { try { person.wait(); } catch (InterruptedException e) { e.printStackTrace(); } } if (x == 0) { person.setName("jony"); person.setAge(33); person.setGender("man"); } else { person.setName("李丽"); person.setAge(23); person.setGender("女"); } x = (x + 1) % 2; person.setFlag(true); person.notify(); } } } public Person getPerson() { return person; } public void setPerson(Person person) { this.person = person; } } //======================= package com.pb.thread.demo3; public class Output implements Runnable { private Person person; public Output(Person person) { this.person = person; } @Override public void run() { while (true) { synchronized (person) { if (!(person.getFlag())) { try { person.wait(); } catch (InterruptedException e) { e.printStackTrace(); } } System.out.println("姓名:" + person.getName() + "年龄:" + person.getAge() + ",性别:" + person.getGender()); person.setFlag(false); person.notify(); } } } public Person getPerson() { return person; } public void setPerson(Person person) { this.person = person; } } //==================== package com.pb.thread.demo3; /** * * @author Denny *wait(),notify(),notifyAll() *都使用在同步中,因为要对持胡监视器(锁)的线程操作 *因为只有同步才有锁 *为什么这些操作线程的方法要定义在Object类中呢? *国为这些方法在操作线程时,都必须要标识它们所操作作线程只有的锁 *只有同一个锁上的被等待,可以被同一个锁上的notify()唤醒 *不可以对不同锁中的线程唤醒 *等待和唤醒必须是同一个锁。 *锁可以是任意对象,可以被任意对象调用的方法在Object中. */ public class Test { public static void main(String[] args) { Person person=new Person(); Input input=new Input(person); Output output = new Output(person); Thread t1=new Thread(input); Thread t2=new Thread(output); t1.start(); t2.start(); } }
优化以上代码
package com.pb.thread.demo3; /** * * @author Denny * 线程间通讯: * 其它就是多个线程在操作同一个资源 * 只是操作的动作不同 * */ public class Person { private String name; private int age; private String gender; private boolean flag; public synchronized void setThis(String name,int age,String gender){ if(flag){ try { wait(); } catch (InterruptedException e) { e.printStackTrace(); } } this.name=name; this.age=age; this.gender=gender; this.flag=true; notify(); } public synchronized void getThis(){ if(!flag){ try { wait(); } catch (InterruptedException e) { e.printStackTrace(); } } System.out.println("姓名:" + this.name + "年龄:" + this.age + ",性别:" + this.gender); this.flag=false; notify(); } public String getName() { return name; } public void setName(String name) { this.name = name; } public int getAge() { return age; } public void setAge(int age) { this.age = age; } public String getGender() { return gender; } public void setGender(String gender) { this.gender = gender; } public boolean getFlag() { return flag; } public void setFlag(boolean flag) { this.flag = flag; } } //==================== package com.pb.thread.demo3; public class Input implements Runnable { private Person person; public Input(Person person) { this.person = person; } @Override public void run() { int x = 0; while (true) { if (x == 0) { person.setThis("jony", 33,"man"); } else { person.setThis("李丽", 23,"女"); } x = (x + 1) % 2; } } public Person getPerson() { return person; } public void setPerson(Person person) { this.person = person; } } //======================== package com.pb.thread.demo3; public class Output implements Runnable { private Person person; public Output(Person person) { this.person = person; } @Override public void run() { while (true) { person.getThis(); } } public Person getPerson() { return person; } public void setPerson(Person person) { this.person = person; } } //================= package com.pb.thread.demo3; /** * * @author Denny *wait(),notify(),notifyAll() *都使用在同步中,因为要对持胡监视器(锁)的线程操作 *因为只有同步才有锁 *为什么这些操作线程的方法要定义在Object类中呢? *国为这些方法在操作线程时,都必须要标识它们所操作作线程只有的锁 *只有同一个锁上的被等待,可以被同一个锁上的notify()唤醒 *不可以对不同锁中的线程唤醒 *等待和唤醒必须是同一个锁。 *锁可以是任意对象,可以被任意对象调用的方法在Object中. */ public class Test { public static void main(String[] args) { Person person=new Person(); new Thread(new Input(person)).start(); new Thread(new Output(person)).start(); /* Input input=new Input(person); Output output = new Output(person); Thread t1=new Thread(input); Thread t2=new Thread(output); t1.start(); t2.start();*/ } }
姓名:李丽年龄:23,性别:女 姓名:jony年龄:33,性别:man 姓名:李丽年龄:23,性别:女 姓名:jony年龄:33,性别:man 姓名:李丽年龄:23,性别:女 姓名:jony年龄:33,性别:man
2.1、单个生产者和单个消费者
package com.pb.thread.demo4; public class Product { private String name; private int count; private boolean flag; //生产 public synchronized void set(String name){ if(flag){ try { wait(); } catch (InterruptedException e) { e.printStackTrace(); } } this.name=name+"..."+count++; System.out.println(Thread.currentThread().getName()+"---生产者---"+this.name); this.flag=true; notify(); } public synchronized void get(){ if(!flag){ try { wait(); } catch (InterruptedException e) { e.printStackTrace(); } } System.out.println(Thread.currentThread().getName()+"--------消费者------------"+name); this.flag=false; notify(); } } //====================== package com.pb.thread.demo4; public class Producter implements Runnable { private Product product; public Producter(Product product){ this.product=product; } @Override public void run() { while(true){ product.set("产品"); } } } //================ package com.pb.thread.demo4; public class Consumer implements Runnable { private Product product; public Consumer(Product product){ this.product=product; } @Override public void run() { while(true){ product.get(); } } } //================ package com.pb.thread.demo4; public class Test { public static void main(String[] args) { Product p=new Product(); Producter producter=new Producter(p); Consumer consumer=new Consumer(p); Thread t1=new Thread(producter); Thread t2=new Thread(consumer); t1.start(); t2.start(); } }
结果:
Thread-0---生产者---产品...20901 Thread-1--------消费者------------产品...20901 Thread-0---生产者---产品...20902 Thread-1--------消费者------------产品...20902 Thread-0---生产者---产品...20903 Thread-1--------消费者------------产品...20903 Thread-0---生产者---产品...20904 Thread-1--------消费者------------产品...20904 Thread-0---生产者---产品...20905 Thread-1--------消费者------------产品...20905 Thread-0---生产者---产品...20906 Thread-1--------消费者------------产品...20906 Thread-0---生产者---产品...20907 Thread-1--------消费者------------产品...20907 Thread-0---生产者---产品...20908 Thread-1--------消费者------------产品...20908
2.2、多个生产者和多个消费者
package com.pb.thread.demo4; public class Product { private String name; private int count; private boolean flag; //生产 public synchronized void set(String name){ while(flag){ //修改为循环判断 try { wait(); } catch (InterruptedException e) { e.printStackTrace(); } } this.name=name+"..."+count++; System.out.println(Thread.currentThread().getName()+"---生产者---"+this.name); this.flag=true; notifyAll(); //修改为notifyAll(); } public synchronized void get(){ while(!flag){//修改为循环判断 try { wait(); } catch (InterruptedException e) { e.printStackTrace(); } } System.out.println(Thread.currentThread().getName()+"--------消费者------------"+name); this.flag=false; notifyAll();//修改为notifyAll(); } }
一、Lock
Lock
实现提供了比使用 synchronized
方法和语句可获得的更广泛的锁定操作。此实现允许更灵活的结构,可以具有差别很大的属性,可以支持多个相关的 Condition
对象。
public interface Condition
Condition
将 Object
监视器方法(wait
、notify
和 notifyAll
)分解成截然不同的对象,以便通过将这些对象与任意 Lock
实现组合使用,为每个对象提供多个等待 set(wait-set)。其中,Lock
替代了 synchronized
方法和语句的使用,Condition
替代了 Object 监视器方法的使用。
package com.pb.thread.demo4; import java.util.concurrent.locks.*; public class Product { private String name; private int count; private boolean flag; Lock lock = new ReentrantLock();// 声明锁对象 // 声明2个condition对象来表示生产者和消费都,如果有多个可以声明多个 // 显示声明 Condition condition_pro = lock.newCondition();// 生产者 Condition condition_con = lock.newCondition(); // 生产 public void set(String name) { // 加锁 lock.lock(); try { while (flag) { // 修改为循环判断 condition_pro.await(); // 指定对象锁睡觉 } this.name = name + "..." + count++; System.out.println(Thread.currentThread().getName() + "---生产者---" + this.name); this.flag = true; // 唤醒指定线程锁 condition_con.signal();// 唤醒消费都线程 } catch (InterruptedException e) { e.printStackTrace(); } finally { // 释放锁 lock.unlock(); } } public void get() { // 加锁 lock.lock(); try { while (!flag) { //消费对象锁上 condition_con.await(); } System.out.println(Thread.currentThread().getName() + "--------消费者------------" + name); this.flag = false; //唤醒生产者 condition_pro.signal(); } catch (InterruptedException e) { e.printStackTrace(); } finally { //释放锁 lock.unlock(); } } }
4.1、线程常用方法
No.
|
方法名称
|
类型
|
描述
|
1
|
public Thread(Runnable target)
|
构造
|
接收Runnable接口子类对象,实例化Thread对象
|
2
|
public Thread(Runnable target,String name)
|
构造
|
接收Runnable接口子类对象,实例化Thread对象,并设置线程名称
|
3
|
public Thread(String name)
|
构造
|
实例化Thread对象,并设置线程名称
|
4
|
public static Thread currentThread()
|
普通
|
返回目前正在执行的线程
|
5
|
public final String getName()
|
普通
|
返回线程的名称
|
6
|
public final int getPriority()
|
普通
|
发挥线程的优先级
|
7
|
public boolean isInterrupted()
|
普通
|
判断目前线程是否被中断,如果是,返回true,否则返回false
|
8
|
public final boolean isAlive()
|
普通
|
判断线程是否在活动,如果是,返回true,否则返回false
|
9
|
public final void join() throws InterruptedException
|
普通
|
等待线程死亡
|
10
|
public final synchronized void join(long millis) throws InterruptedException
|
普通
|
等待millis毫秒后,线程死亡
|
11
|
public void run()
|
普通
|
执行线程
|
12
|
public final void setName(String name)
|
普通
|
设定线程名称
|
13
|
public final void setPriority(int newPriority)
|
普通
|
设定线程的优先值
|
14
|
public static void sleep(long millis) throws InterruptedException
|
普通
|
使目前正在执行的线程休眠millis毫秒
|
15
|
public void start()
|
普通
|
开始执行线程
|
16
|
public static void yield()
|
普通
|
将目前正在执行的线程暂停,允许其它线程执行
|
17
|
public final void setDaemon(boolean on)
|
普通
|
将一个线程设置成后台运行
|
18
|
public final void setPriority(int newPriority)
|
普通
|
更改线程的优先级
|
5.1、守护线程-后台资源
setDaemon
public final void setDaemon(boolean on)将该线程标记为守护线程或用户线程。
当正在运行的线程都是守护线程时,Java 虚拟机退出。
该方法必须在启动线程前调用。
该方法首先调用该线程的 checkAccess 方法,且不带任何参数。这可能抛出 SecurityException(在当前线程中)。
参数:
on - 如果为 true,则将该线程标记为守护线程。
抛出:
IllegalThreadStateException - 如果该线程处于活动状态。
SecurityException - 如果当前线程无法修改该线程。
当前台线程都结束时,后台线程自动结束。
5.2、线程优先级
setPriority
public final void setPriority(int newPriority)更改线程的优先级。
首先调用线程的 checkAccess 方法,且不带任何参数。这可能抛出 SecurityException。
在其他情况下,线程优先级被设定为指定的 newPriority 和该线程的线程组的最大允许优先级相比较小的一个。
参数:
newPriority - 要为线程设定的优先级
抛出:
IllegalArgumentException - 如果优先级不在 MIN_PRIORITY 到 MAX_PRIORITY 范围内。
10-----1------------5
static int |
MAX_PRIORITY 线程可以具有的最高优先级。 |
static int |
MIN_PRIORITY
线程可以具有的最低优先级。 |
static int |
NORM_PRIORITY
分配给线程的默认优先级。 |
SecurityException - 如果当前线程无法修改该线程。
getPriority
public final int getPriority()返回线程的优先级。
返回:
该线程的优先级。
作用:阻塞指定的线程等到另一个线程完成以后,再继续执行
package com.pb.thread.demo2; public class MyThread implements Runnable { @Override public void run() { for(int x=0;x<10;x++){ System.out.println(Thread.currentThread().getName()+"....."+x); } } } //============= package com.pb.thread.demo2; public class Demo { public static void main(String[] args) { MyThread my=new MyThread(); Thread t1=new Thread(my); t1.setName("半路加入的线程"); for(int x=0;x<10;x++){ if(x==5){ try { t1.start(); t1.join(); } catch (InterruptedException e) { e.printStackTrace(); } } System.out.println(Thread.currentThread().getName()+"....."+x); } } }
结果:
main.....0 main.....1 main.....2 main.....3 main.....4 半路加入的线程.....0 半路加入的线程.....1 半路加入的线程.....2 半路加入的线程.....3 半路加入的线程.....4 半路加入的线程.....5 半路加入的线程.....6 半路加入的线程.....7 半路加入的线程.....8 半路加入的线程.....9 main.....5 main.....6 main.....7 main.....8 main.....9
或者
package com.pb.thread.demo2; public class Test { public static void main(String[] args) { for(int x=0;x<10;x++){ if(x==5){ try { Thread t1=new Thread(new MyThread(),"半路加入的线程"); t1.start(); t1.join(); } catch (InterruptedException e) { e.printStackTrace(); } } System.out.println(Thread.currentThread().getName()+"....."+x); } } }
yield
public static void yield()暂停当前正在执行的线程对象,并执行其他线程。
package com.pb.thread.demo2; public class MyThread implements Runnable { @Override public void run() { for(int x=0;x<10;x++){ System.out.println(Thread.currentThread().getName()+"....."+x); Thread.yield(); } } } //=========== package com.pb.thread.demo2; public class Test { public static void main(String[] args) { new Thread(new MyThread(),"线程一").start(); new Thread(new MyThread(),"线程二").start(); } }
八、停止线程
开启多线程,运行代码通常是循环结构
只要控制住循环,就可以让run方法结束。也就是线程结束。
package com.pb.thread.demo4; public class StopThread implements Runnable { private boolean flag=true; @Override public void run() { while(flag){ System.out.println(Thread.currentThread().getName()+"......run"); } } public void setChangeFlag(){ this.flag=false; } public static void main(String[] args) { StopThread st=new StopThread(); Thread t1=new Thread(st); Thread t2=new Thread(st); t1.start(); t2.start(); int num=0; while(true){ if(num++==60){ st.setChangeFlag(); break; } System.out.println(Thread.currentThread().getName()+"===="+num); } } }
interrupt
public void interrupt()
如果线程在调用 Object
类的 wait()
、wait(long)
或 wait(long, int)
方法,或者该类的 join()
、join(long)
、join(long, int)
、sleep(long)
或 sleep(long, int)
方法过程中受阻,则其中断状态将被清除,它还将收到一个 InterruptedException
。
package com.pb.thread.demo4; public class StopThread implements Runnable { private boolean flag = true; @Override public synchronized void run() { while (flag) { try { wait(); } catch (InterruptedException e) { // e.printStackTrace(); System.out.println(Thread.currentThread().getName() + "......Exception"); flag = false; //设置标识为false } System.out.println(Thread.currentThread().getName() + "......run"); } } public void setChangeFlag() { this.flag = false; } public static void main(String[] args) { StopThread st = new StopThread(); Thread t1 = new Thread(st); Thread t2 = new Thread(st); t1.start(); t2.start(); int num = 0; while (true) { if (num++ == 60) { //中断状态也就是冻结状态,回到运行状态 t1.interrupt(); t2.interrupt(); break; } System.out.println(Thread.currentThread().getName() + "====" + num); } System.out.println("over"); } }
main====1 main====2 main====3 main====4 main====5 main====6 main====7 main====8 main====9 main====10 main====11 main====12 main====13 main====14 main====15 main====16 main====17 main====18 main====19 main====20 main====21 main====22 main====23 main====24 main====25 main====26 main====27 main====28 main====29 main====30 main====31 main====32 main====33 main====34 main====35 main====36 main====37 main====38 main====39 main====40 main====41 main====42 main====43 main====44 main====45 main====46 main====47 main====48 main====49 main====50 main====51 main====52 main====53 main====54 main====55 main====56 main====57 main====58 main====59 main====60 over Thread-1......Exception Thread-1......run Thread-0......Exception Thread-0......run
九、sleep();
sleep
public static void sleep(long millis) throws InterruptedException
在指定的毫秒数内让当前正在执行的线程休眠(暂停执行),此操作受到系统计时器和调度程序精度和准确性的影响。该线程不丢失任何监视器的所属权。
参数:
millis
- 以毫秒为单位的休眠时间。
抛出:
InterruptedException
- 如果任何线程中断了当前线程。当抛出该异常时,当前线程的中断状态 被清除。
toString
public String toString()
返回该线程的字符串表示形式,包括线程名称、优先级和线程组。
package com.pb.thread.demo4; public class StopThread implements Runnable { private boolean flag = true; @Override public synchronized void run() { while (flag) { System.out.println(Thread.currentThread().toString()+ "......run"); } } public void setChangeFlag() { this.flag = false; } public static void main(String[] args) { StopThread st = new StopThread(); Thread t1 = new Thread(st); Thread t2 = new Thread(st); t1.start(); t2.start(); int num = 0; while (true) { if (num++ == 60) { st.setChangeFlag(); break; } System.out.println(Thread.currentThread().toString()+ "====" + num); } System.out.println("over"); } }
Thread[Thread-0,5,main]......run Thread[main,5,main]====1 Thread[Thread-0,5,main]......run Thread[main,5,main]====2 Thread[Thread-0,5,main]......run Thread[main,5,main]====3 Thread[Thread-0,5,main]......run Thread[main,5,main]====4 Thread[main,5,main]====5 Thread[main,5,main]====6 Thread[main,5,main]====7 Thread[Thread-0,5,main]......run Thread[Thread-0,5,main]......run Thread[Thread-0,5,main]......run Thread[Thread-0,5,main]......run Thread[Thread-0,5,main]......run Thread[Thread-0,5,main]......run Thread[Thread-0,5,main]......run Thread[Thread-0,5,main]......run Thread[Thread-0,5,main]......run Thread[Thread-0,5,main]......run Thread[Thread-0,5,main]......run Thread[Thread-0,5,main]......run Thread[Thread-0,5,main]......run Thread[Thread-0,5,main]......run Thread[Thread-0,5,main]......run Thread[Thread-0,5,main]......run Thread[Thread-0,5,main]......run Thread[Thread-0,5,main]......run Thread[Thread-0,5,main]......run Thread[Thread-0,5,main]......run Thread[Thread-0,5,main]......run Thread[Thread-0,5,main]......run Thread[Thread-0,5,main]......run Thread[Thread-0,5,main]......run Thread[Thread-0,5,main]......run Thread[Thread-0,5,main]......run Thread[Thread-0,5,main]......run Thread[Thread-0,5,main]......run Thread[Thread-0,5,main]......run Thread[Thread-0,5,main]......run Thread[Thread-0,5,main]......run Thread[Thread-0,5,main]......run Thread[Thread-0,5,main]......run Thread[main,5,main]====8 Thread[Thread-0,5,main]......run Thread[Thread-0,5,main]......run Thread[Thread-0,5,main]......run Thread[Thread-0,5,main]......run Thread[Thread-0,5,main]......run Thread[Thread-0,5,main]......run Thread[Thread-0,5,main]......run Thread[Thread-0,5,main]......run Thread[Thread-0,5,main]......run Thread[Thread-0,5,main]......run Thread[main,5,main]====9 Thread[Thread-0,5,main]......run Thread[main,5,main]====10 Thread[Thread-0,5,main]......run Thread[Thread-0,5,main]......run Thread[Thread-0,5,main]......run Thread[Thread-0,5,main]......run Thread[Thread-0,5,main]......run Thread[Thread-0,5,main]......run Thread[Thread-0,5,main]......run Thread[Thread-0,5,main]......run Thread[Thread-0,5,main]......run Thread[Thread-0,5,main]......run Thread[Thread-0,5,main]......run Thread[Thread-0,5,main]......run Thread[Thread-0,5,main]......run Thread[Thread-0,5,main]......run Thread[Thread-0,5,main]......run Thread[main,5,main]====11 Thread[Thread-0,5,main]......run Thread[Thread-0,5,main]......run Thread[Thread-0,5,main]......run Thread[Thread-0,5,main]......run Thread[Thread-0,5,main]......run Thread[Thread-0,5,main]......run Thread[Thread-0,5,main]......run Thread[Thread-0,5,main]......run Thread[Thread-0,5,main]......run Thread[Thread-0,5,main]......run Thread[Thread-0,5,main]......run Thread[Thread-0,5,main]......run Thread[Thread-0,5,main]......run Thread[Thread-0,5,main]......run Thread[Thread-0,5,main]......run Thread[Thread-0,5,main]......run Thread[Thread-0,5,main]......run Thread[Thread-0,5,main]......run Thread[Thread-0,5,main]......run Thread[Thread-0,5,main]......run Thread[Thread-0,5,main]......run Thread[main,5,main]====12 Thread[main,5,main]====13 Thread[main,5,main]====14 Thread[main,5,main]====15 Thread[main,5,main]====16 Thread[Thread-0,5,main]......run Thread[main,5,main]====17 Thread[main,5,main]====18 Thread[main,5,main]====19 Thread[main,5,main]====20 Thread[main,5,main]====21 Thread[main,5,main]====22 Thread[main,5,main]====23 Thread[main,5,main]====24 Thread[main,5,main]====25 Thread[main,5,main]====26 Thread[main,5,main]====27 Thread[main,5,main]====28 Thread[main,5,main]====29 Thread[main,5,main]====30 Thread[main,5,main]====31 Thread[main,5,main]====32 Thread[main,5,main]====33 Thread[main,5,main]====34 Thread[main,5,main]====35 Thread[main,5,main]====36 Thread[main,5,main]====37 Thread[main,5,main]====38 Thread[main,5,main]====39 Thread[main,5,main]====40 Thread[main,5,main]====41 Thread[main,5,main]====42 Thread[main,5,main]====43 Thread[main,5,main]====44 Thread[main,5,main]====45 Thread[main,5,main]====46 Thread[main,5,main]====47 Thread[main,5,main]====48 Thread[main,5,main]====49 Thread[main,5,main]====50 Thread[main,5,main]====51 Thread[main,5,main]====52 Thread[main,5,main]====53 Thread[main,5,main]====54 Thread[main,5,main]====55 Thread[main,5,main]====56 Thread[main,5,main]====57 Thread[main,5,main]====58 Thread[main,5,main]====59 Thread[main,5,main]====60 over Thread[Thread-0,5,main]......run
Thread[Thread-0,5,main]......run Thread[main,5,main]====1 Thread[Thread-0,5,main]......run Thread[main,5,main]====2 Thread[Thread-0,5,main]......run Thread[main,5,main]====3 Thread[Thread-0,5,main]......run Thread[main,5,main]====4 Thread[main,5,main]====5 Thread[main,5,main]====6 Thread[main,5,main]====7 Thread[Thread-0,5,main]......run Thread[Thread-0,5,main]......run Thread[Thread-0,5,main]......run Thread[Thread-0,5,main]......run Thread[Thread-0,5,main]......run Thread[Thread-0,5,main]......run Thread[Thread-0,5,main]......run Thread[Thread-0,5,main]......run Thread[Thread-0,5,main]......run Thread[Thread-0,5,main]......run Thread[Thread-0,5,main]......run Thread[Thread-0,5,main]......run Thread[Thread-0,5,main]......run Thread[Thread-0,5,main]......run Thread[Thread-0,5,main]......run Thread[Thread-0,5,main]......run Thread[Thread-0,5,main]......run Thread[Thread-0,5,main]......run Thread[Thread-0,5,main]......run Thread[Thread-0,5,main]......run Thread[Thread-0,5,main]......run Thread[Thread-0,5,main]......run Thread[Thread-0,5,main]......run Thread[Thread-0,5,main]......run Thread[Thread-0,5,main]......run Thread[Thread-0,5,main]......run Thread[Thread-0,5,main]......run Thread[Thread-0,5,main]......run Thread[Thread-0,5,main]......run Thread[Thread-0,5,main]......run Thread[Thread-0,5,main]......run Thread[Thread-0,5,main]......run Thread[Thread-0,5,main]......run Thread[main,5,main]====8 Thread[Thread-0,5,main]......run Thread[Thread-0,5,main]......run Thread[Thread-0,5,main]......run Thread[Thread-0,5,main]......run Thread[Thread-0,5,main]......run Thread[Thread-0,5,main]......run Thread[Thread-0,5,main]......run Thread[Thread-0,5,main]......run Thread[Thread-0,5,main]......run Thread[Thread-0,5,main]......run Thread[main,5,main]====9 Thread[Thread-0,5,main]......run Thread[main,5,main]====10 Thread[Thread-0,5,main]......run Thread[Thread-0,5,main]......run Thread[Thread-0,5,main]......run Thread[Thread-0,5,main]......run Thread[Thread-0,5,main]......run Thread[Thread-0,5,main]......run Thread[Thread-0,5,main]......run Thread[Thread-0,5,main]......run Thread[Thread-0,5,main]......run Thread[Thread-0,5,main]......run Thread[Thread-0,5,main]......run Thread[Thread-0,5,main]......run Thread[Thread-0,5,main]......run Thread[Thread-0,5,main]......run Thread[Thread-0,5,main]......run Thread[main,5,main]====11 Thread[Thread-0,5,main]......run Thread[Thread-0,5,main]......run Thread[Thread-0,5,main]......run Thread[Thread-0,5,main]......run Thread[Thread-0,5,main]......run Thread[Thread-0,5,main]......run Thread[Thread-0,5,main]......run Thread[Thread-0,5,main]......run Thread[Thread-0,5,main]......run Thread[Thread-0,5,main]......run Thread[Thread-0,5,main]......run Thread[Thread-0,5,main]......run Thread[Thread-0,5,main]......run Thread[Thread-0,5,main]......run Thread[Thread-0,5,main]......run Thread[Thread-0,5,main]......run Thread[Thread-0,5,main]......run Thread[Thread-0,5,main]......run Thread[Thread-0,5,main]......run Thread[Thread-0,5,main]......run Thread[Thread-0,5,main]......run Thread[main,5,main]====12 Thread[main,5,main]====13 Thread[main,5,main]====14 Thread[main,5,main]====15 Thread[main,5,main]====16 Thread[Thread-0,5,main]......run Thread[main,5,main]====17 Thread[main,5,main]====18 Thread[main,5,main]====19 Thread[main,5,main]====20 Thread[main,5,main]====21 Thread[main,5,main]====22 Thread[main,5,main]====23 Thread[main,5,main]====24 Thread[main,5,main]====25 Thread[main,5,main]====26 Thread[main,5,main]====27 Thread[main,5,main]====28 Thread[main,5,main]====29 Thread[main,5,main]====30 Thread[main,5,main]====31 Thread[main,5,main]====32 Thread[main,5,main]====33 Thread[main,5,main]====34 Thread[main,5,main]====35 Thread[main,5,main]====36 Thread[main,5,main]====37 Thread[main,5,main]====38 Thread[main,5,main]====39 Thread[main,5,main]====40 Thread[main,5,main]====41 Thread[main,5,main]====42 Thread[main,5,main]====43 Thread[main,5,main]====44 Thread[main,5,main]====45 Thread[main,5,main]====46 Thread[main,5,main]====47 Thread[main,5,main]====48 Thread[main,5,main]====49 Thread[main,5,main]====50 Thread[main,5,main]====51 Thread[main,5,main]====52 Thread[main,5,main]====53 Thread[main,5,main]====54 Thread[main,5,main]====55 Thread[main,5,main]====56 Thread[main,5,main]====57 Thread[main,5,main]====58 Thread[main,5,main]====59 Thread[main,5,main]====60 over Thread[Thread-0,5,main]......run
package com.pb.thread.demo4; /* * 匿名内部类实现多线程 */ public class ThreadTest { public static void main(String[] args) { //线程对象 new Thread(){ public void run(){ for (int x = 0; x < 100; x++) { System.out.println(Thread.currentThread().getName()+".........."+x); } } }.start(); //Runnable 接口 Runnable r=new Runnable(){ public void run(){ for (int x = 0; x < 100; x++) { System.out.println(Thread.currentThread().getName()+".........."+x); } } }; //启动线程 new Thread(r).start(); } }
标签:
原文地址:http://www.cnblogs.com/liunanjava/p/4813289.html