----------------------android培训、java培训、期待与您交流! ---------------------
java中实现多线程操作有两种手段,一种继承自Thread类,另一种是实现Runnable接口。
一、继承Thread
Thread类是在java.lang包中定义的,一个类只要继承了Thread类,此类就称为多线程实现类。在Thread子类中,必须明确地覆写Thread类中的run()方法,此方法为线程的主体。
class MyThread extends Thread{ // 继承Thread类,作为线程的实现类 private String name ; // 表示线程的名称 public MyThread(String name){ this.name = name ; // 通过构造方法配置name属性 } public void run(){ // 覆写run()方法,作为线程 的操作主体 for(int i=0;i<10;i++){ System.out.println(name + "运行,i = " + i) ; } } } public class ThreadDemo01{ public static void main(String args[]){ MyThread mt1 = new MyThread("线程A ") ; // 实例化对象 MyThread mt2 = new MyThread("线程B ") ; // 实例化对象 mt1.run() ; // 调用线程主体 mt2.run() ; // 调用线程主体 } }
二、实现Runnable接口,Runnable接口中只定义了,一个抽象方法。
class MyThread implements Runnable{ // 实现Runnable接口,作为线程的实现类
private String name ; // 表示线程的名称
public MyThread(String name){
this.name = name ; // 通过构造方法配置name属性
}
public void run(){ // 覆写run()方法,作为线程 的操作主体
for(int i=0;i<10;i++){
System.out.println(name + "运行,i = " + i) ;
}
}
}
public class RunnableDemo01{
public static void main(String args[]){
MyThread mt1 = new MyThread("线程A ") ; // 实例化对象
MyThread mt2 = new MyThread("线程B ") ; // 实例化对象
Thread t1 = new Thread(mt1) ; // 实例化Thread类对象
Thread t2 = new Thread(mt2) ; // 实例化Thread类对象
t1.start() ; // 启动多线程
t2.start() ; // 启动多线程
}
}
三、线程间通信:
多个线程在操作同一个资源,但是操作的动作不同。等待唤醒机制:
class Apple { String name; String color; boolean flag = false; } class Input implements Runnable { private Apple r ; Input(Apple r) { this.r = r; } public void run() { int x = 0; while(true) { synchronized(r) { if(r.flag) //标志位,如果flag=true,那么说明已经有数据,线程等待 try{r.wait();}catch(Exception e){} if(x==0) { r.name="a"; r.color="red"; } else { r.name="b"; r.color = "yellow"; } x = (x+1)%2; r.flag = true;//修改标志位 r.notify();//唤醒输出线程 } } } } class Output implements Runnable { private Apple r ; Output(Apple r) { this.r = r; } public void run() { while(true) { synchronized(r) { if(!r.flag)//如果线程的标志位flag=false,线程等待 try{r.wait();}catch(Exception e){} System.out.println(r.name+"...."+r.color); r.flag = false; r.notify();//唤醒输入线程 } } } } class InputOutputTest { public static void main(String[] args) { Apple r = new Apple(); Input in = new Input(r); Output out = new Output(r); Thread t1 = new Thread(in); Thread t2 = new Thread(out); t1.start(); t2.start(); } }
总结:
wait();notify();notifyALL();
为什么这些操作线程饿方法要定义Object类中呢?因为这些方法在操作同步线程时,都必须要标识他们所操作的线程只有的锁。只有在同一个锁上的被等待线程,可以被同一个锁notify唤醒。不可以对不同锁中的线程进行唤醒。也就说,等待和唤醒必须是同一个锁。而锁可以使任意对象个,所以可以被任意对象调用的方法定义object类中。
终止线程只有一种,run方法结束。开启多线程运行,运行代码通常是循环结构。只要控制住循环,就可以让run方法结束,也就是线程结束。特殊情况:当线程处于了冻结状态。就不会读取到标记。那么线程就不会结束。当没有指定的方式让冻结的线程恢复到运行状态是,这时需要对冻结进行清除。强制让线程恢复到运行状态中来。这样就可以操作标记让线程结束。Thread类提供该方法 interrupt();
四、关于run()和start()分析:
总结:class MyThread extends Thread{ public void run(){ try { Thread.currentThread().sleep(3000); } catch (InterruptedException e) { } System.out.println("MyThread running"); } } public class ThreadTest{ public static void main(String argv[]) { MyThread t = new MyThread(); t.run(); t.start(); System.out.println("Thread Test"); } }
代码分析过程:MyThread t = new MyThread();创建了一个线程。
t.run();调用MyThread对象的run方法。这是只有一个线程在运行就是主线程。当主线程执行到了run方法中的sleep(3000);时。这是主线程处于冻结状态。程序并没有任何执行。当3秒过后,主线程打印了 MyThread running。 run方法执行结束。
t.start();开启了t线程。有两种可能情况。
t线程获取执行权,调用自己的run方法。然后执行的sleep(3000);冻结3秒。3秒后,打印MyThread running t线程结束,整个程序结束。
第二种,主线程执行到t.start();开启了t线程,t线程就直接获取到了执行权。就调用自己的run方法。指定到sleep(3000).t线程冻结3秒,这是t线程就是释放了执行权。那么主线程开始执行打印了Thread Test,主线程结束。
----------------------android培训、java培训、期待与您交流! ---------------------