java的多线程机制上

来源:互联网 发布:自定义oid取不到数据 编辑:程序博客网 时间:2024/05/27 14:16


一、多线程概述
package com.laobi.day12;public class ThreadTest01 {/** * 进程:正在进行中的程序(直译) *       * 线程:就是进程中一个程序执行的控制单元(执行路径) *      一个进程中可以多执行路径,称之为多线程 *       * 一个进程中至少要有一个线程 *  * 开启多个线程是为了同时运行多部分代码 *  * 每一个线程都有自己运行的内容。这个内容可以称为线程要执行的任务 *  * 多线程的好处:解决了多部分同时运行的问题 * 多线程的弊端:线程太多会导致效率的降低 *  * 其实应用程序的执行都是cpu在做着快速的切换完成的。这个切换时随机的。 *  * jvn启动时就启动了多个线程,至少有两个线程可以分析出来的 * 1、执行main函数的线程 *    该线程的任务代码都定义在main函数中 * 2、负责垃圾回收的线程 *  *  * @param artcool */public static void main(String[] args) {Demo d1 = new Demo("旺财");  //主线程运行示例Demo d2 = new Demo("小强");d1.show();d2.show();//new Demo();      jvm线程演示//System.gc();System.out.println("diu");}}class Demo{private String name;public Demo(String name) {super();this.name = name;}public void show(){for(int x=0;x<10;x++){for(int y=0;y<999999999;y++){}System.out.println("demo 走"+name+"..."+x);}}}


二、创建线程

package com.laobi.day12;public class ThreadTest02 {/** * 如何创建一个线程呢? * 创建线程方式一:继承Thread类 *  * 步骤: * 1、定义一个类继承Thread类。 *  * 2、覆盖Thread类中的run方法。 *  * 3、直接创建Thread的子类对象 * 4、调用start方法开启线程并调用线程的任务run方法执行 *  * 可以通过Thread的getName获取线程的名称  Thread——编号 *  * 主线程的名字就是main * @param args */public static void main(String[] args) {/*创建线程的目的是为了开启一条执行路径,去运行指定的代码和其他代码实现同时运行而运行的指定代码就是这个执行路径的主任务jvm创建的主线程的任务都定义在了主函数中而自定义的线程它的任务在哪?Thread类用于描述线程,线程是需要任务的。所以Thread类也对任务的描述这个任务就是通过Thread类中的run方法来体现。也就是说,run方法就是封装自定义线程运行任务的函数run方法中定义就是线程要运行的代码任务开启线程是为了运行指定代码,所以只有继承Thread类,并复写run方法*///Thread t1 = new Thread();Demo2 d1 = new Demo2("jack");Demo2 d2 = new Demo2("tom");d1.start();d2.start();}}class Demo2 extends Thread{private String name;Demo2(String name){this.name = name;}public void run(){show();}public void show(){for(int x=0;x<10;x++){for(int y=0;y<999999;y++){}System.out.println(name+"...."+x+"..."+Thread.currentThread().getName());}}}


三、Thread类的基本获取和设置方法

1)获取线程名字
  
  Thread类中方法  String getName()

  在一个不是Thread子类中获取名字:
  Thread类中静态方法
     static Thread currentThread()
  返回正在运行的,当前线程对象  Thread类对象
  继续使用线程对象的 getName()获取线程的名字
  
  
  Thread类的方法 void setName(String name)设置线程名
  Thread(String name) 用的是Thread类构造方法
  子类使用super访问父类构造器
  
  
  在Thread子类中,获取线程名字,直接使用父类方法getName()
  在不是Thread子类中,通用代码,Thread.currentThread().getName()
四、线程的优先级的获取和设置
  
  Thread类方法getPriority() 获取到优先级
  Thread类方法setPriority(int t) 设置优先级

package com.test.xiancheng;public class Test07 {/** *线程的生命周期及状态转换 *1、新建状态(new) *   创建一个线程对象后,该线程对象就处于新建状态,此时它不能运行,和其他Java对象 *   一样,仅仅由Java虚拟机为其分配了内存,没有表现出任何线程的动态特征 *2、就绪状态(runnable) *   当线程对象调用了Start()方法后,线程就进入就绪状态了。 *   此时它只是具备了运行条件,能否获得cpu的使用权开始运行,还需要等待系统的调度 *3、运行状态(running) *   如果出就绪状态的线程获得了cpu的使用权,开始执行run()方法中的线程执行体,则该线程处于运行状态。 *4、阻塞状态(blocked) *   一个正在执行的线程在某些特殊情况下,如执行耗时的输入/输出操作时,会放弃cpu使用权,进入阻塞状态。 *   阻塞就不能进入阻塞状态后,就不能进入排队队列。 *   例举一下线程由运行状态转换成阻塞状态的原因 *   a、当线程试图获取某个对象的同步锁时,如果该锁被其他线程所持有,则当前线程会进入阻塞状态, *      如果想从阻塞状态进入就绪状态必须获得其他线程所持有的锁 *   b、当线程调用了一个阻塞式的io方法时,该线程就会进入阻塞状态,如果想进入就绪状态就必须要等到这个阻塞的 *      io方法返回 *   c、当线程调用了某个对象的wait()时,也会使线程进入阻塞状态,如果想进入就绪状态就需要使用 *      notify()方法唤醒该线程 *   d、当线程调用了Thread的sleep(long mills)方法时,也会使线程进入阻塞状态,在这种情况下 *      只需等到线程的睡眠时间到了以后,线程就会自动进入就绪状态 *   f、当在一个线程中调用另一个线程的join()方法时,会使当前线程进入阻塞状态,在这种情况下,需要等到 *      需要等到新加入的线程运行结束后才会结束阻塞状态,进入就绪状态 *   线程从阻塞状态只能进入就绪状态 *5、死亡状态(Terminated) *    线程的run()方法正常执行完毕或者线程抛出一个未捕获的异常(Exception)、错误(Error),线程 *    就会进入死亡状态。一旦进入死亡状态I,线程将不再拥有运行的资格,也不能再转换到其他状态 * * *线程的调度:分别是分时调度模型和抢占式调度模型 *分时调度:让所用的线程轮流获得cpu的使用权,并且平均分配cpu的时间片 *抢占式调度:让可运行池中优先级高的线程优先占用cpu,而对优先级相同的 *          线程,随机选择一个线程占用cpu,当它失去cpu的使用权后, *          再随机选择其他线程获取cpu使用权。 *1、线程的优先级: *   如果需要对线程进行调度,最直接的方式就是设置线程的优先级 *2、线程休眠: *   使正在执行的线程暂停,将cpu让给别的线程,这是可以使用sleep(),该方法可以让当前正在执行 *   的线程暂停一段时间,进入休眠等待状态。 *3、线程让步: *   可以通过yield()方法来实现,该方法和sleep有点相似,都可以让正在运行的线程暂停, *   区别在于yield()方法不会阻塞线程,他只是将线程转换成就绪状态,让系统调度器重新调度一次 *4、线程插队: *   当在某个线程中调用其他线程的join()方法时,调用的线程将被阻塞,直到 *   被join()方法加入的线程执行完成后他才会继续运行 *    *        * 多线程同步: * 1、线程安全 * 2、线程同步方法 * 3、同步方法:当把共享资源的操作放在synchronized定义的区域内时,便为这些操作加了同步锁 *              在方法前面同样可以使用synchronized关键字来修饰,被修饰的方法为同步方法,它能实现 *              和同步代码块同样的功能。被synchronized修饰的方法在某一时刻只允许一个线程访问 *              ,访问该方法的其他线程都会被阻塞,直到当前线程访问完毕后,其他线程才有机会执行方法 * */public static void main(String[] args) {Thread minPriorty = new Thread(new MinProirty(),"优先级较低的线程");Thread maxPriorty = new Thread(new MaxPriorty(),"优先级较高的线程");minPriorty.setPriority(Thread.MIN_PRIORITY);maxPriorty.setPriority(10);maxPriorty.start();minPriorty.start();}}class MaxPriorty implements Runnable{public void run(){for(int i=0;i<=10;i++){System.out.println(Thread.currentThread().getName()+"正在输出:"+i);}}}class MinProirty implements Runnable{public void run(){for(int i=0;i<=10;i++){System.out.println(Thread.currentThread().getName()+"正在输出:"+i);}}}


五、线程休眠

package com.test.xiancheng;public class XCxiumian {/** * 线程休眠: *   使正在执行的线程暂停,将cpu让给别的线程,这是可以使用sleep(),该方法可以让当前正在执行 *   的线程暂停一段时间,进入休眠等待状态。 * @throws Exception  */public static void main(String[] args) throws Exception {new Thread(new SleepThread()).start();for(int i=1;i<=10;i++){if(i==5){Thread.sleep(2000);}System.out.println("主线程正在输出:"+i);Thread.sleep(500);}}}class SleepThread implements Runnable{public void run(){for(int i=1;i<=10;i++){if(i==3){try{Thread.sleep(2000);}catch(InterruptedException e){e.printStackTrace();}}System.out.println("线程一正在输出:"+i);try{Thread.sleep(500);}catch(Exception e){e.printStackTrace();}}}}



五、线程让步

package com.test.xiancheng;public class XCrangbu {/** * 线程让步: *   可以通过yield()方法来实现,该方法和sleep有点相似,都可以让正在运行的线程暂停, *   区别在于yield()方法不会阻塞线程,他只是将线程转换成就绪状态,让系统调度器重新调度一次 *     */public static void main(String[] args) {Thread t1 = new YieldThread("线程A");Thread t2 = new YieldThread("线程B");t1.start();t2.start();}}class YieldThread extends Thread{public YieldThread(String name){super(name);}public void run(){for(int i=0;i<5;i++){System.out.println(Thread.currentThread().getName()+"----"+i);if(i==3){System.out.print("线程让步:");Thread.yield();//线程运行到此,做出让步}}}}


六、线程插队

package com.test.xiancheng;public class XCchadui {public static void main(String[] args) throws Exception {Thread t = new Thread(new EmergencyThread(),"线程一");t.start();for(int i=1;i<6;i++){System.out.println(Thread.currentThread().getName()+"输入:"+i);if(i==2){t.join();}Thread.sleep(500);}}}class EmergencyThread implements Runnable{public void run(){for(int i=1;i<6;i++){System.out.println(Thread.currentThread().getName()+"输入:"+i);try{Thread.sleep(500);}catch(InterruptedException e){e.printStackTrace();}}}}


 

0 0