当前位置:首页 > 芯闻号 > 充电吧
[导读]关于Java中的线程                  1. 进程   进程:正在运行的程序,所占有内存空间   程序存储在硬盘,运行时期到了内存中   线程:是一个大程序中的子程序   CPU真正执

关于Java中的线程                  
1. 进程   进程:正在运行的程序,所占有内存空间   程序存储在硬盘,运行时期到了内存中   线程:是一个大程序中的子程序   CPU真正执行的是线程,子程序对于CPU来讲独立执行路径,路径就是线程 //====================================================== 2. Java中创建线程   任何都是对象,线程也是对象,对象的描述类   java.lang.Thread类   创建线程的第一种方式,继承Thread类,重写run方法   创建Thread子类对象   调用子类中的方法start()开启线程    void start()           使该线程开始执行;Java 虚拟机调用该线程的 run 方法。   JVM 本身是单线程的程序,还是多线程的程序   一个线程运行我们写的程序,一个线程不定时收取垃圾,JVM帮助你调用Windows中的功能   为什么继承Thread类,入伙,继承Thread类,子类就是一个线程了   为什么重写run方法 Thread中的run方法是空方法,等待子类重写   线程运行的程序是什么,未知的,Java工程师,开放多线程技术的时候   不知道使用Java编程的人员会运行哪些代码   提供一个标准,就是run方法:不管线程运行哪些代码,必须放在run中,线程就运行你run中的代码
/*  * 创建线程第一种方式,继承Thread类  */ class Demo1 extends Thread{  public void run(){   for(int x = 0 ; x < 50 ;x++){    System.out.println("run..."+x);   }  } } public class ThreadDemo1 {  public static void main(String[] args) {   while(true){   Demo1 d = new Demo1();   d.start();//开启线程,JVM自动调用线程的run方法   for(int x = 0 ; x < 50 ; x++){    System.out.println("main..."+x);   }   }  } }
//======================================================
4. 线程的状态图,必须自己会画
5. 线程名字的获取和设置   获取名字,Thread类的方法getName(),返回字符串   线程名字JVM命名的 Thread-0 Thread-1   在Thread子类中,直接使用父类方法getName()获取名字   在不是Thread子类中,获取线程名字   Thread类中,提供了一个静态方法 currentThread()返回值是一个Thread类的对象   方法,返回当前线程对象,既然返回的是对象,方法调用链    String name = Thread.currentThread().getName();   设置线程的名字:     Thread类的方法setName()     Thread类的构造方法       Thread(String name)传递线程名字     Thread子类中,super语句将线程的名字送到父类构造方法


class ThreadName extends Thread{  ThreadName(String name){   super(name);  }  public void run(){   String name =Thread.currentThread().getName();   System.out.println(name+" 线程ThreadName");  } } public class ThreadDemo {  public static void main(String[] args) {   //Thread.currentThread();//返回的就是运行main方法的线程对象   String name = Thread.currentThread().getName();   System.out.println(name);   ThreadName t1 = new ThreadName("西班牙0");   ThreadName t2 = new ThreadName("智利2");    // t1.setName("小强");  // t2.setName("旺财");     t1.start();   t2.start();  } }
//====================================================== 6. 售票的一个案例   利用多线程模拟多窗口一起售票   模拟出了,卡机线程,导致了数据的安全问题   多线程操作同一个数据的时候,出现数据安全问题      解决办法:一个线程不执行完毕,其他的线程,不能执行     Java中开放出了同步技术,保证线程的安全性,会阻止其他线程进入   同步代码块     synchronized(任意对象){            线程操作的共享数据     }

/*  * 模拟售票4个窗口一起出售  * 改造成实现Runnable接口的方式  */ class Ticket implements Runnable{  private int tickets = 100;  private Object obj = new Object();  public void run(){   while(true){    synchronized(obj){    if(tickets > 0){     //线程if判断完毕后,休眠一段时间     try{     Thread.sleep(67);     }catch(Exception e){}     System.out.println(Thread.currentThread().getName()+"..出售第.."+tickets--);    }    }   }  } } public class ThreadDemo1 {  public static void main(String[] args) {   //创建Ticket对象   Ticket t = new Ticket();   //创建Thread类对象,传递Runnable接口的实现类对象   Thread t1 = new Thread(t);   Thread t2 = new Thread(t);   Thread t3 = new Thread(t);   Thread t4 = new Thread(t);   t1.start();   t2.start();   t3.start();   t4.start();  } }
//====================================================== 7. 创建线程的第二种方式   定义类,实现Runnable接口   重写run方法   class A implements Runnable{         public void run(){  }   }   A类不再是线程类了   直接创建Thread类对象   构造方法Thread(Runnable target) 接受的数据类型是Runnable接口的子类类型   new Thread(new A());    调用Thread类中的start();
  两个线程的创建方式的区别   继承Thread类,实现Runnable接口区别   继承,单继承局限性   接口,多现实,避免了单继承的局限性   继承Thread类方式,线程中的数据是对象自己的   实现接口方法,线程中的数据是共享的   写多线程程序推荐使用接口方式 //====================================================== 8. 同步的原理     synchronized(任意对象){            线程操作的共享数据     }     对象,写在了同步中   专业名词,对象监视器   通俗一点:锁   线程进到同步代码块后,线程获取这把锁,这扇门永久关闭了   当线程出去同步代码块,将锁释放   厕所原理   多线程操作同一个数据,安全问题   如果是单线程,没有数据安全问题


//====================================================== 9. 模拟存钱   一张卡,可以多个柜台存钱   余额是0,每个柜台每次存100元   两个柜台,每个存3次   600元,没存一次,查看余额   同步方法,在方法的声明上写同步关键字   线程每次只有一个运行这个方法   当方法中所有代码都是线程操作的的共享数据   同步方法中,锁是什么   确定的是,锁肯定有,锁必须是对象   锁是本类的对象引用this   方法中的同步代码块,锁直接写this   静态方法中的,同步锁是谁   锁是对象!   静态优先于对象,静态中的锁,是本类的class文件对象   Java中,每一个数据类型,JVM都赋予他们一个静态成员变量   class名字,变量的运行结果就是类的class文件对象   静态方法中的锁,就是本类.class字节码文件对象

/*  * 存钱的时候  * 卡,钱,到银行中去,银行柜台存钱  * 但是,整个Add方法中的所有代码,都是线程操作的共享数据  * 没有必要同步一段代码,同步整个方法  */ class Bank{  //存钱功能,存一次,看余额  private static int sum = 0;  public static synchronized void add(int money){  // synchronized(Bank.class){   sum = sum + money;   System.out.println(sum);  // }  } } class Customer implements Runnable{  private Bank b = new Bank();  public void run(){   for(int x = 0 ; x < 3 ; x++){   Bank.add(100);   }  } } public class ThreadDemo2 {  public static void main(String[] args) {   Customer c = new Customer();   Thread t1 = new Thread(c);   Thread t2 = new Thread(c);   t1.start();   t2.start();  } }

//============================================================== 10. 单例模式   懒汉有安全隐患,多线程并发访问懒汉式的时候   安全问题,同步避免   效率很低,提高懒汉的效率   第一次执行s=null   进同步 创建对象,返回   第二次执行s!=null   没有必要进同步了,直接返回   两次判断,提高效率
class Single{  private Single(){}  private static Single s = null;  public static Single getInstance(){     if(s == null){     synchronized(Single.class){   if( s == null)    s = new Single();         }   }     return s;  } } class SingleThead implements Runnable{  public void run(){   for(int x = 0 ; x < 30 ; x++){    Single s = Single.getInstance();    System.out.println(s);   }  } }
//============================================================== 11. 死锁案例   在多线程的技术中,两个或者两个以上的线程,同时争夺一个对象监视器   导致程序的假死现象   死锁:出现条件,必须多线程,争夺一个锁,程序中,体现在同步代码块的嵌套效果   死锁的案例,面试过程中经常被考到 //============================================================== 12. 线程的通信   两个线程同时对一个资源对象,进行赋值和取值操作   思考,数据安全问题怎么发生的   发生后,怎么解决   数据安全问题:线程的随机性导致程序数据安全隐患   采用了同步技术,依然没有解决   当你发现数据安全问题后,使用了同步技术,还是不能解决     第一点,确定程序是不是多线程在操作共享数据 确定     第二点,使用的同步中的锁,是同一把锁吗,锁不同唯一的       必须将锁变成唯一的对象,才能控制数据安全问题       资源对象,数据的安全性解决了
  线程等待和唤醒的方法   没有出现在线程描述类Thread类中   方法定义在了Object类中,为什么这样设计   原因是锁,锁是一个对象,对象是通过类new出来的   锁是哪一个类的对象,无法确定的   但是将方法写在Object类中,所有的类的对象,都具有线程的等待与唤醒方法   wait()方法的使用,将线程永久等待,直到有人唤醒   wait方法必须有锁的支持,wait方法必须写在同步中   锁是唯一的   synchronized(r){      wait();      notify();   }   synchronized(r){      notify()   }   IllegalMonitorStateException   异常,运行时期的异常,抛出该异常,说明wait notify没有锁的支持,没有对象监视器
/*  * 线程通信的代码的优化  */ //定义资源类,私有处理 class Recource{  private String name;  private String sex;  private boolean flag = false;  //提供get set方法,访问成员变量  public synchronized void set(String name,String sex){   if(flag)    try{    this.wait();    }catch(Exception e){}   this.name = name;   this.sex = sex;   flag = true;   this.notify();  }  public synchronized void get(){   if(!flag)    try{    this.wait();    }catch(Exception e){}   System.out.println(name+"..."+sex);   flag = false;   this.notify();  } } //输入线程 class Input implements Runnable{  private Recource r;  Input(Recource r){this.r = r;}  public void run(){   int x = 0 ;   while(true){    if(x %2 == 0){     r.set("张三", "男");    }else{     r.set("李四", "女");    }    x++;   }  } } //输出的线程 class Output implements Runnable{  private Recource r ;  Output(Recource r){this.r=r;}  public void run(){   while(true){    r.get();   }  } } public class ThreadDemo5 {  public static void main(String[] args) {   Recource r = new Recource();   new Thread(new Input(r)).start();   new Thread(new Output(r)).start();  } }

//============================================================== 13. wait() sleep() 导致线程等待,两个方法区别在哪里(不要光看表面。)      sleep(毫秒值)自动醒来   wait()永久等待,需要别的线程唤醒
  sleep()方法是Thread类的静态方法   wait()方法是Object类的非静态方法
  sleep()不需要对象锁   wait()必须有锁的支持
  sleep()方法,执行的时候线程不会释放对象锁   wait()方法,执行的时候,线程放弃对象锁,被唤醒的时候,从新获取对象锁,才能运行 //============================================================== 14. 定时器   Java程序中,有定时功能,按照一定的时间间隔运行指定的程序   定时器类,java.util.Timer   构造方法     Timer(boolean isDaemon) false 不是守护的线程     schedule(TimerTask task, Date firstTime, long period)                        定时器任务              第一次时间         间隔   抽象类 TimerTask 时间任务,定时器执行的程序,写在这个类的run方法

/*class Time extends TimerTask{  public void run(){   System.out.println("定时2秒钟发送一次邮件");  } }*/ public class TimerDemo {  public static void main(String[] args) {   Timer t = new Timer(false);     t.schedule(new TimerTask(){    public void run(){     System.out.println(""定时2秒钟发送一次邮件"");    }   }, new Date(), 3600000);     System.out.println("main...over");  } }

//==============================================================
15. 多线程通信,生产者与消费者   一个产品,分别线程控制,一个控制生产,一个控制消费   生产一个,消费一个,多生产者,多消费者   多个生产与多个消费,全部的唤醒notifyAll()   唤醒以后,数据安全性还是没解决   线程在wait上等待,被唤醒的时候,从Wait这里起来   起来以后,不会再次判断flag是true,还是false,因此数据问题,没哟解决   线程,被唤醒以后,但是判断标记!!   用的是循环的方式,解决线程倒下去后,再起来,必须还要判断标记   但是发现一个问题:     notifyAll()唤醒了全部等待的线程     1个活的,7个等着,全部醒来     浪费资源,能不能唤醒对方的一个线程的     生产者,只唤醒一个消费者     消费者,只唤醒一个生产者     唤醒本方是没有意义,全部唤醒是浪费资源的     Java的JDK1.4版本之前,是做不到了     到了JDK1.5版本后,就可以实现了     提供一套新的多线程的操作方式     synchronized,被替换了     wait(),notify(),notifyAll(),被替换了     JDK1.5的新特性,线程锁定操作     导包 java.util.concurrent.locks


//============================================================== 16. JDK1.5的锁 lock接口   Lock接口--synchronized同步   同步是有锁提供   接口中,定义了两个方法 lock() unlock()   要同步线程的时候,使用这两个方法,进行锁操作   Lcok接口的实现类对象ReentrantLock   获取到接口的实现类对象,调用方法,锁操作   新的技术中,JDK提供了一个接口Condition   替换了原有线程方法,wait,notify   将线程进行分组管理   t1-t4 set方法,用锁就是set方法中的锁   t5-t8 get方法,用锁就是get方法中的锁   一个lock接口上,可以实现多个Condition对象   final Condition notFull = lock.newCondition();   final Condition notEmpty = lock.newCondition();   将一个接口Lock,分成两组管理   Condition接口中的三个方法    await() -- wait()    signal() -- notify()    signalAll() -- notifyAll();

/*  * 将案例,改造成lock锁方式实现功能  */ import java.util.concurrent.locks.*; class Product{  private String name;  //定义计数器  private int count ;  //定义标识  private boolean flag = false;  //定义Lock锁对象  private Lock lock = new ReentrantLock();  //通过Lock接口,获取Condition对象  private Condition pro = lock.newCondition();  private Condition cus = lock.newCondition();    //定义生产方法  public void set(String name){   //获取锁   lock.lock();   while(flag)    try{      pro.await();    }catch(Exception e){}   this.name = name + count++;   System.out.println(Thread.currentThread().getName()+"生产第..."+this.name);   flag = true;   //this.notifyAll();   //释放锁   cus.signal();   lock.unlock();  }    //定义消费方法  public void get(){   lock.lock();   while(!flag)    try{    cus.await();    }catch(Exception e){}   System.out.println(Thread.currentThread().getName()+"消费第........."+this.name);   flag = false;   //this.notifyAll();   pro.signal();   lock.unlock();  } } //定义生产者 class Producter implements Runnable{  private Product p ;  Producter(Product p){this.p = p;}  public void run(){   while(true){    p.set("键盘");   }  } } //定义消费这 class Customer implements Runnable{  private Product p ;  Customer(Product p){this.p = p;}  public void run(){   while(true){    p.get();   }  } } public class ThreadDemo {  public static void main(String[] args) {   Product p = new Product();   Producter producter = new Producter(p);   Customer customer = new Customer(p);   Thread t1 = new Thread(producter);   Thread t2 = new Thread(producter);   Thread t3 = new Thread(producter);   Thread t4 = new Thread(producter);   Thread t5 = new Thread(customer);   Thread t6 = new Thread(customer);   Thread t7 = new Thread(customer);   Thread t8 = new Thread(customer);   t1.start();   t2.start();   t3.start();   t4.start();   t5.start();   t6.start();   t7.start();   t8.start();  } }

//========================================================== 17. 线程的停止方式   Thread类中,有一个方法stop(),过时
  终止线程的运行,目的结束run方法就行   停止线程的第一种方式,改变变量的值,结束while循环,结束了run方法    处于等待中的线程,怎么停下   例子:     我有一个朋友,失眠,找了一个催眠大师(水平很高)     进行了催眠,朋友就睡了(wait())     催眠师说,被我催眠的人,只有我能叫醒     催眠师死了,不能让朋友永久的等待下去     拍你一板砖,醒来,收到了伤害(异常)     线程的第二种停止方式     void interrupt() + 异常停下,等待中的线程     打击线程方法,处于等待的线程,将会抛出异常
/*  * 线程如何停止下来  */ class StopThread implements Runnable{  private boolean flag = true;  public void run(){   while(flag){    synchronized(this){     try{this.wait();}catch(Exception e){      e.printStackTrace();      //System.out.println(e.getMessage()+"打你一板砖");      flag = false;     }    System.out.println("run....");    }   }  }  public void setFlag(boolean flag){   this.flag = flag;  } } public class ThreadDemo1 {  public static void main(String[] args) {   StopThread st = new StopThread();   Thread t = new Thread(st);   t.start();   for(int x = 0 ; x < 1000 ; x++){   if(x==999)       //st.setFlag(false);    t.interrupt();   else    System.out.println("main"+x);   }  } }
//========================================================== 18. 守护线程   Thread类中。setDaemon(boolean )传递是true,线程守护线程   如果所有运行的线程,都是守护线程,JVM退出
  方法,必须在start开始前调用
  Feiq,开启多个聊天窗口的时候,一旦关闭飞秋主程序,聊天窗口也就关闭了   聊天窗口线程,就是飞秋主线程的守护线程,一旦主线程死亡,所有的守护线程就死亡
/*  * 守护线程  */ class ThreadDaemon implements Runnable{  public void run(){   while(true)   System.out.println("run....");  } } public class ThreadDemo2 {  public static void main(String[] args) {   ThreadDaemon td = new ThreadDaemon();   Thread t = new Thread(td);   t.setDaemon(true);   t.start();  } }


//========================================================== 19. Thread中其他方法,toString() setPriority() join() yield()   toString()继承Object,重写toString()   Thread[Thread-0,5,main]   5 优先级,main 线程组   优先级三个级别,最低,默认,最高   setPriority(int )设置优先级   但是优先级的效果,多核,多线程的CPU上,效果不是很明显了   join() 加入 等待该线程终止   使用join方法的线程,不停止,其他线程运行不了   static yield()
/*  * 线程的让步方法,static yield  */ class YieldThread implements Runnable{  public void run(){   for(int x = 0 ; x < 100 ; x++){    Thread.yield();    System.out.println(Thread.currentThread().getName()+"run.."+x);   }  } } public class ThreadDemo5 {  public static void main(String[] args) {   YieldThread yt = new YieldThread();   Thread t0 = new Thread(yt);   Thread t1 = new Thread(yt);   t0.start();   t1.start();  } }


/*  * 等待该线程终止  */ class JoinThread implements Runnable{  public void run(){   for(int x = 0 ; x < 100; x++){    System.out.println(Thread.currentThread().getName()+"run.."+x);   }  } } public class ThreadDemo4 {  public static void main(String[] args) throws Exception{   JoinThread jt = new JoinThread();   Thread t0 = new Thread(jt);   Thread t1 = new Thread(jt);      t0.start();      t0.join();      t1.start();   for(int x = 0 ;x < 100 ; x++){    System.out.println("main...."+x);   }  } }
/*  * Thread中的toString()  */ class ThreadToString implements Runnable{  public void run(){   for(int x = 0 ; x < 100 ; x++){    System.out.println(Thread.currentThread().getName()+"run.."+x);   }  } } public class ThreadDemo3 {  public static void main(String[] args) {   ThreadToString tts = new ThreadToString();   Thread t0 = new Thread(tts);   Thread t1 = new Thread(tts);   t0.setPriority(Thread.MAX_PRIORITY);   t1.setPriority(Thread.NORM_PRIORITY);   t0.start();   t1.start();  // System.out.println(t);  } }


本站声明: 本文章由作者或相关机构授权发布,目的在于传递更多信息,并不代表本站赞同其观点,本站亦不保证或承诺内容真实性等。需要转载请联系该专栏作者,如若文章内容侵犯您的权益,请及时联系本站删除。
换一批
延伸阅读

9月2日消息,不造车的华为或将催生出更大的独角兽公司,随着阿维塔和赛力斯的入局,华为引望愈发显得引人瞩目。

关键字: 阿维塔 塞力斯 华为

加利福尼亚州圣克拉拉县2024年8月30日 /美通社/ -- 数字化转型技术解决方案公司Trianz今天宣布,该公司与Amazon Web Services (AWS)签订了...

关键字: AWS AN BSP 数字化

伦敦2024年8月29日 /美通社/ -- 英国汽车技术公司SODA.Auto推出其旗舰产品SODA V,这是全球首款涵盖汽车工程师从创意到认证的所有需求的工具,可用于创建软件定义汽车。 SODA V工具的开发耗时1.5...

关键字: 汽车 人工智能 智能驱动 BSP

北京2024年8月28日 /美通社/ -- 越来越多用户希望企业业务能7×24不间断运行,同时企业却面临越来越多业务中断的风险,如企业系统复杂性的增加,频繁的功能更新和发布等。如何确保业务连续性,提升韧性,成...

关键字: 亚马逊 解密 控制平面 BSP

8月30日消息,据媒体报道,腾讯和网易近期正在缩减他们对日本游戏市场的投资。

关键字: 腾讯 编码器 CPU

8月28日消息,今天上午,2024中国国际大数据产业博览会开幕式在贵阳举行,华为董事、质量流程IT总裁陶景文发表了演讲。

关键字: 华为 12nm EDA 半导体

8月28日消息,在2024中国国际大数据产业博览会上,华为常务董事、华为云CEO张平安发表演讲称,数字世界的话语权最终是由生态的繁荣决定的。

关键字: 华为 12nm 手机 卫星通信

要点: 有效应对环境变化,经营业绩稳中有升 落实提质增效举措,毛利润率延续升势 战略布局成效显著,战新业务引领增长 以科技创新为引领,提升企业核心竞争力 坚持高质量发展策略,塑强核心竞争优势...

关键字: 通信 BSP 电信运营商 数字经济

北京2024年8月27日 /美通社/ -- 8月21日,由中央广播电视总台与中国电影电视技术学会联合牵头组建的NVI技术创新联盟在BIRTV2024超高清全产业链发展研讨会上宣布正式成立。 活动现场 NVI技术创新联...

关键字: VI 传输协议 音频 BSP

北京2024年8月27日 /美通社/ -- 在8月23日举办的2024年长三角生态绿色一体化发展示范区联合招商会上,软通动力信息技术(集团)股份有限公司(以下简称"软通动力")与长三角投资(上海)有限...

关键字: BSP 信息技术
关闭
关闭