黑马程序员_Java多线程(一)

android培训java培训

一个进程表示一个程序,在一个程序上可以运行多个子程序,子程序被称为线程。

进程:在一个时间段内只能完成一件事。

线程:在进程基础上划分,在同一时间段内可以比传统进程完成更多的功能。

CPU只有一个,是指在同一个时间段内可以完成多个程序,但在同一个时间点内,只能有一个程序工作。

线程与进程的区别:

多个进程的内部数据和状态都是完全独立的,而多线程是共享一块内存空间和一组系统资源,有可能互相影响。

线程本身的数据通常只有寄存器数据,以及一个程序执行时使用的堆栈,所以线程的切换比进程切换负担要小。

Java的线程可以通过继承java.lang.Thread类来实现,每个线程都是通过某个Thread类对象对应的run()方法来完成操作的,run()方法称为线程体。

Java.lang为java程序默认导入包,一个类只要继承了Thread类,就表示此类实现了多线程,如果在程序中直接调用run()方法,实际上只是调用类.方法,而没有启动操作系统的支持。

class Demo extends Thread{

       private String info;

       public Demo(String info){

              this.info = info;

       }//多线程需要一个主体,子类要覆写Thread类中的run()方法

       public void run(){

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

                     System.out.println(this.info+"i = "+i);  

              }

              System.out.println("");

       }

}

public class JavaDemo127{

       public static void main(String args[]){//如果此程序是一个多线程,肯定会交替运行

              Demo d1 = new Demo("Thread 1: ");

              Demo d2 = new Demo("Thread 2: ");

              Demo d3 = new Demo("Thread 3: ");

              d1.run();

              d2.run();

              d3.run();

       }

}

要执行多线程,则要调用public void start()方法,通过start()调用的是子类中的run()方法,启用多线程。

class Demo extends Thread{

       private String info;

       public Demo(String info){

              this.info = info;

       }//多线程需要一个主体,子类要覆写Thread类中的run()方法

       public void run(){

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

                     System.out.println(this.info+"i = "+i);  

              }

              System.out.println("");

       }

}

public class JavaDemo128{

       public static void main(String args[]){//如果此程序是一个多线程,肯定会交替运行

              Demo d1 = new Demo("Thread 1: ");

              Demo d2 = new Demo("Thread 2: ");

              Demo d3 = new Demo("Thread 3: ");

              d1.start();

              d2.start();

              d3.start();

       }

}

由于类继承有限制,在JDK中提供了Runnable接口,也可以实现多线程,优选接口,避免类的单继承,Thread类实际上也是实现了Runable接口。

class Demo implements Runnable{

       private String info;

       public Demo(String info){

              this.info = info;

       }

       public void run(){

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

                     System.out.println(this.info+"i = "+i);  

              }

              System.out.println("");

       }

}

public class JavaDemo129{

       public static void main(String args[]){

              Demo d1 = new Demo("Thread 1: ");

              Demo d2 = new Demo("Thread 2: ");

              Demo d3 = new Demo("Thread 3: ");

              Thread t1 = new Thread(d1); //Runnable接口要启动线程必须通过Thread

              Thread t2 = new Thread(d2);

              Thread t3 = new Thread(d3);

              t1.start();//通过Thread类的对象启动多线程

              t2.start();

              t3.start();

       }

}

Thread和Runable特点:继承Thread类的多线程之间不能实现资源的共享,而实现Runable接口之后可以实现多个线程之间的资源共享。

例:10张火车票,给4个代售点销售。 Thread类的多线程:

class Demo extends Thread{

       private int ticket=10;

       public void run(){

              while (this.ticket > 0){

                     System.out.println("卖票:"+this.ticket--);

              }

       }

}

public class JavaDemo130{

       public static void main(String args[]){

              Demo d1 = new Demo();//准备4个售票点

              Demo d2 = new Demo();

              Demo d3 = new Demo();

              Demo d4 = new Demo();

              d1.start();//d1.start(); // //无论调用多少遍start()方法一个线程对象只能只启动一次              d2.start();

              d3.start();

              d4.start();

       }

}

class Demo extends Thread{

       private int ticket=10;

       public void run(){

              while (this.ticket > 0){

                     System.out.println("卖票:"+this.ticket--);

              }

       }

}

public class J{

       public static void main(String args[]){

              //准备4个售票点

              Demo d1 = new Demo();

              Thread t1 = new Thread(d1);

              Thread t2 = new Thread(d1);

              Thread t3 = new Thread(d1);

              Thread t4 = new Thread(d1);

              t1.start();

              //d1.start(); //无论调用多少遍start()方法一个线程对象只能只启动一次

              t2.start();

              t3.start();

              t4.start();

       }

}

Runable接口实现的多线程:

class Demo implements Runnable{

       private int ticket=10;

       public void run(){

              while (this.ticket > 0){

                     System.out.println("卖票:"+this.ticket--);

              }

       }

}

public class JavaDemo131{

       public static void main(String args[]){

              Demo d = new Demo();//4个售票点应该控制同一资源

              Thread t1 = new Thread(d);

              Thread t2 = new Thread(d);

              Thread t3 = new Thread(d);

              Thread t4 = new Thread(d);

              t1.start();//t1.start();//线程只启动一次

              t2.start();

              t3.start();

              t4.start();

       }

}

 

线程启动之后要等待CUP进行调度,并不是立刻启动。

所有的线程操作就是指Thread类的操作,当前运行的线程可以指当前操作这个方法的线程。

取得当前运行的线程:public static Thread currentThread()

class Demo implements Runnable{

       public void fun(){//public static Thread currentThread()方法表示取得当前运行的线程

              System.out.println(Thread.currentThread());

       }

       public void run(){

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

                     this.fun();

              }

       }

}

public class JavaDemo133{

       public static void main(String args[]){

              Demo d = new Demo();

              Thread t1 = new Thread(d);

              Thread t2 = new Thread(d);

              Thread t3 = new Thread(d);

              t1.start();

              t2.start();

              t3.start();

       }

}

取得线程名称、设置线程名称:在Thread API中使用getName()、setName()

class Demo implements Runnable{

       public void fun(){

              //getName()表示取得当前线程的名字默认线程名:Thread-0

              System.out.println(Thread.currentThread().getName()+"在运行...");

       }

       public void run(){

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

                     this.fun();

              }

       }

}

public class JavaDemo134{

       public static void main(String args[]){

              Demo d = new Demo();

              Thread t1 = new Thread(d,"线程1");

              Thread t2 = new Thread(d,"线程1");

              Thread t3 = new Thread(d,"线程1");

              /*通过构造方法修改线程名

              t1.setName("线程1");

              t2.setName("线程2");

              t3.setName("线程3");*/

              t1.start();

              t2.start();

              t3.start();

       }

}

main()方法也是一个线程,之前所有的程序都是基于多线程的运行机制:在main方法中通过对象.方法调用的一切代码都是主线程。

class Demo implements Runnable{

       public void fun(){

              System.out.println(Thread.currentThread().getName()+"在运行...");

       }

       public void run(){

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

                     this.fun();

              }

       }

}

public class JavaDemo135{

       public static void main(String args[]){

              Demo d = new Demo();

              Thread t1 = new Thread(d,"线程1");

              t1.start();

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

                     d.fun();//main方法也是一个线程

              }

       }

}

isAlive():用来检测线程是否启动而且仍然启动,结果没有固定内容,因为线程有可能优先完成,也可能在最后执行。

class Demo implements Runnable{

       public void run(){

                     System.out.println(Thread.currentThread().getName()+"在运行...");   

       }

}

public class JavaDemo136{

       public static void main(String args[]){

              Demo d = new Demo();

              Thread t1 = new Thread(d,"线程1");

              System.out.println("线程启动以前:"+t1.isAlive());

              t1.start();

              System.out.println("线程启动以后:"+t1.isAlive());

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

                     ;//加入一个延迟

              }

              System.out.println("线程延迟以后:"+t1.isAlive());

       }

}

Public static voidsleep():用于将线程短暂休眠。sleep()需要try...catch...

class Demo implements Runnable{

       public void fun(){

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

                     try{

                            Thread.sleep(1000);//sleep()需要try...catch...

                     }catch (Exception e){

                     }

                     System.out.println(Thread.currentThread().getName()+"在运行...");   

              }

       }

       public void run(){

                     this.fun();

       }

}

public class JavaDemo137{

       public static void main(String args[]){

              Demo d = new Demo();

              Thread t1 = new Thread(d,"线程1");

              Thread t2 = new Thread(d,"线程2");

              t1.start();

              t2.start();

       }

}

Public final voidjoin():强制某一个线程运行,指一个线程必须运行完成之后其他线程才可以继续运行。需要try...catch...

class Demo implements Runnable{

       public void run(){

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

                     System.out.println(Thread.currentThread().getName()+"运行中....i= "+i);

              }

       }

}

public class JavaDemo138{

       public static void main(String args[]){

              Thread t = new Thread(new Demo(),"线程t");

              t.start();

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

                     if (i == 10){

                            try{

                                   t.join();//强制运行一个线程,直到线程结束

                            }catch (Exception e){

                            }

                     }

                     System.out.println(Thread.currentThread().getName()+"线程运行中....i= "+i);

              }

       }

}

 

Public void interrupt():当一个线程运行时,另一个线程可以调用interrup()来中断它。

class Demo implements Runnable{

       public void run(){

              System.out.println("1、Demo --->程序进入休眠状态!!!");

              try{

                     Thread.sleep(20000);

              }catch (Exception e){

                     System.out.println("2、Demo --->程序休眠被中断!!!");

                     return;//返回调用处

              }

              System.out.println("3、Demo --->程序休眠正常退出!!!");

       }

}

public class JavaDemo139{

       public static void main(String args[]){

              Thread t = new Thread(new Demo(),"线程t");

              System.out.println(t.getName()+"--->线程启动");

              t.start();

              System.out.println("4、main--->线程休眠");

              try{

                     Thread.sleep(2000);

              }catch (Exception e){

              }

              System.out.println("5、main--->中断线程");

              t.interrupt();

              System.out.println("6、main--->退出线程");

       }

}

Public BooleanisInterrupted():检查线程中断的状态。

public class JavaDemo140 extends Object {

       public static void main(String[] args) {

              Thread t = Thread.currentThread();

              System.out.println("Point A: t.isInterrupted()=" + t.isInterrupted());

              t.interrupt();

              System.out.println("Point B: t.isInterrupted()=" + t.isInterrupted());

              System.out.println("Point C: t.isInterrupted()=" + t.isInterrupted());

              try {

                     Thread.sleep(2000);

                     System.out.println("was NOT interrupted");

              } catch ( InterruptedException x ) {

                     System.out.println("was interrupted");

              }// 在这里因为sleep抛出了异常,所以它清除了中断标志

                     System.out.println("Point D: t.isInterrupted()=" + t.isInterrupted());

       }

}

线程如果中断之后在休眠,则会清除标志。

线程同步:方法同步:

class Demo implements Runnable

{

       private int ticket = 10 ;

       public synchronized void fun(){// 加入一个同步方法把需要同步的地方放在同步方法之中

              if(this.ticket>0){//保护

                     try{

                            Thread.sleep(100) ;

                     }catch (Exception e){

                     }

                     System.out.println(Thread.currentThread().getName()+" --> 卖票:"+this.ticket--) ;

              }

       }

       public void run()

       {

              while(ticket>0){//保护

                     this.fun() ;

              }

       }

};

public class JavaDemo141

{

       public static void main(String args[])

       {

              Demo d = new Demo() ;

              Thread t1 = new Thread(d,"售票点 A") ;

              Thread t2 = new Thread(d,"售票点 B") ;

              Thread t3 = new Thread(d,"售票点 C") ;

              t1.start() ;

              t2.start() ;

              t3.start() ;

       }

};

线程同步:同步代码块:

class Demo implements Runnable{

       private int ticket = 10;

       public void run(){

              while (this.ticket > 0){

                     synchronized(this){ //需要一个同步对象对当前线程同步

                            if (this.ticket > 0){

                                   try{

                                          Thread.sleep(100);

                                   }catch (Exception e){

                                   }

                                   System.out.println(Thread.currentThread().getName()+"售票:"+ticket--);

                            }

                     }

              }

       }

}

public class JavaDemo142{

       public static void main(String args[]){

              Demo d = new Demo();

              Thread t1 = new Thread(d,"售票点A");

              Thread t2= new Thread(d,"售票点B");

              Thread t3 = new Thread(d,"售票点C");

              t1.start();

              t2.start();

              t3.start();

       }

}

同步会产生死锁问题,就是在多线程中由于处理不当而造成停止运行的一种状态。模拟死锁:

class DemoA{

       public synchronized void funA(DemoB db){

              System.out.println("DemoA --->进入DemoA中的funA()");

              db.fun2();

       }

       public synchronized void fun2(){

              System.out.println("DemoA --->public synchronized void fun2()");

       }

}

class DemoB{

       public synchronized void funB(DemoA da){

              System.out.println("DemoB --->进入DemoB中的funB()");

              da.fun2();

       }

       public synchronized void fun2(){

              System.out.println("DemoB --->public synchronized void fun2()");

       }

}

class ThreadDead implements Runnable{

       private DemoA da = new DemoA();

       private DemoB db = new DemoB();

       public ThreadDead(){

              new Thread(this).start();

              da.funA(db);

       }

       public void run(){

              db.funB(da);

       }

}

public class JavaDemo143{

       public static void main(String args[]){

              new ThreadDead();

       }

}

同步的经典范例:生产者和消费者

class Person{

       String name;

       String content;

}

class Pro implements Runnable{

       private Person per ;

       public Pro(Person per){

              this.per = per;

       }

       public void run(){

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

                     if (i%2 == 0){    

                            per.name = "李岩";

                            try{

                                   Thread.sleep(100);

                            }catch (Exception e){

                            }

                            per.content = "作者";

                     }else{

                            per.name = "李小岩";

                            try{

                                   Thread.sleep(100);

                            }catch (Exception e){

                            }

                            per.content = "天才";

                     }

              }

       }

}

class Cust implements Runnable{

       private Person per ;

       public Cust(Person per){

              this.per = per;

       }

       public void run(){

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

                     try{

                            Thread.sleep(100);

                     }catch (Exception e){

                     }

                     System.out.println(per.name+"--->"+per.content);

              }

       }

}

public class JavaDemo144{

       public static void main(String args[]){

              Person per = new Person();

              Pro p = new Pro(per);

              Cust c = new Cust(per);

              new Thread(p).start();

              new Thread(c).start();

       }

}

class Person{

       private String name;

       private String content;

       public synchronized void set(String name,String content){

              this.name = name;

              try{Thread.sleep(100);

              }catch (Exception e){

              }

              this.content = content;

       }

       public synchronized String get(){

              return this.name+"--->"+this.content;

       }

}

class Pro implements Runnable{

       private Person per ;

       public Pro(Person per){

              this.per = per;

       }

       public void run(){

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

                     if (i%2 == 0){    

                            per.set("李岩","作者");

                     }else{

                             per.set("李小岩","天才");

                     }

              }

       }

}

class Cust implements Runnable{

       private Person per ;

       public Cust(Person per){

              this.per = per;

       }

       public void run(){

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

                     try{

                            Thread.sleep(100);

                     }catch (Exception e){

                     }

                     System.out.println(per.get());

              }

       }

}

public class JavaDemo145{

       public static void main(String args[]){

              Person per = new Person();

              Pro p = new Pro(per);

              Cust c = new Cust(per);

              new Thread(p).start();

              new Thread(c).start();

       }

}

class Person{

       private String name;

       private String content;

       private boolean flag = false;

       public synchronized void set(String name,String content){

              //判断:如果为绿灯时表示可以设置,否则等待true flase为不可以设置

              if (flag){

                     try{

                            wait();

                     }catch (Exception e){

                     }

              }

              this.name = name;

              try{Thread.sleep(100);

              }catch (Exception e){

              }

              this.content = content;

              flag = true;

              notifyAll();

       }

       public synchronized String get()

       {

              if(!flag){

                     try{

                            wait() ;

                     }catch (Exception e)  {

                     }

              }

              String str = this.name+" --> "+this.content ;

              // 如果为红灯,则表示可以取,否则等待:false

              flag = false ;

              notifyAll() ;

              return str ;

       }

}

class Pro implements Runnable{

       private Person per ;

       public Pro(Person per){

              this.per = per;

       }

       public void run(){

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

                     if (i%2 == 0){    

                            per.set("李岩","作者");

                     }else{

                             per.set("李小岩","天才");

                     }

              }

       }

}

class Cust implements Runnable{

       private Person per ;

       public Cust(Person per){

              this.per = per;

       }

       public void run(){

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

                     try{

                            Thread.sleep(100);

                     }catch (Exception e){

                     }

                     System.out.println(per.get());

              }

       }

}

public class JavaDemo146{

       public static void main(String args[]){

              Person per = new Person();

              Pro p = new Pro(per);

              Cust c = new Cust(per);

              new Thread(p).start();

              new Thread(c).start();

       }

}

线程的等待及唤醒:

Wait():告诉当前线程放弃监视器并进入睡眠状态,直到其他线程进入同一监视器并调用notify为止。

Notify():唤醒wait的第一个线程。有序

notifyAll():唤醒wait中的所有线程。无序

控制线程的生命周期:

class Demo implements Runnable{

       boolean flag = true;

       public void run(){

              int i = 0;

              while (flag){

                     System.out.println("运行 i = "+i++);

              }

       }

}

public class JavaDemo147{

       public static void main(String args[]){

              Demo d = new Demo();

              Thread t = new Thread(d);

              t.start();

              try{

                     Thread.sleep(100) ;

              }catch (Exception e)  {

              }

              d.flag = false;

       }

}

 


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值