A股上市公司传智教育(股票代码 003032)旗下技术交流社区北京昌平校区

 找回密码
 加入黑马

QQ登录

只需一步,快速开始

© 不二晨 金牌黑马   /  2018-8-13 10:01  /  400 人查看  /  3 人回复  /   0 人收藏 转载请遵从CC协议 禁止商业使用本文

累计时间 2小时




  • /*



  • * 创建一个子线程,完成1-100之间自然数的输出。同样地,主线程执行同样的操作



  • * 创建多线程的第一种方式:继承java.lang.Thread类



  • */



  • //1.创建一个继承于Thread的子类



  • class SubThread extends Thread{



  •         //2.重写Thread类的run()方法.方法内实现此子线程要完成的功能



  •         public void run(){



  •                 for(int i = 1;i <= 100;i++){



  •                         System.out.println(Thread.currentThread().getName() +":" + i);



  •                 }



  •         }



  • }







  • public class TestThread {



  •         public static void main(String[] args) {



  •                 //3.创建子类的对象



  •                 SubThread st1 = new SubThread();



  •                 SubThread st2 = new SubThread();







  •                 //4.调用线程的start():启动此线程;调用相应的run()方法



  •                 //一个线程只能够执行一次start()



  •                 //不能通过Thread实现类对象的run()去启动一个线程



  •                 st1.start();







  •                 //st.start();



  •                 //st.run();



  •                 st2.start();







  •                 for(int i = 1;i <= 100;i++){



  •                         System.out.println(Thread.currentThread().getName() +":" + i);



  •                 }



  •         }



  • }




  • /*



  • * Thread的常用方法:



  • * 1.start():启动线程并执行相应的run()方法



  • * 2.run():子线程要执行的代码放入run()方法中



  • * 3.currentThread():静态的,调取当前的线程



  • * 4.getName():获取此线程的名字



  • * 5.setName():设置此线程的名字



  • * 6.yield():调用此方法的线程释放当前CPU的执行权



  • * 7.join():在A线程中调用B线程的join()方法,表示:当执行到此方法,A线程停止执行,直至B线程执行完毕,



  • * A线程再接着join()之后的代码执行



  • * 8.isAlive():判断当前线程是否还存活



  • * 9.sleep(long l):显式的让当前线程睡眠l毫秒



  • * 10.线程通信:wait()   notify()  notifyAll()



  • *



  • * 设置线程的优先级



  • * getPriority() :返回线程优先值



  •    setPriority(int newPriority) :改变线程的优先级







  • */



  • class SubThread1 extends Thread {



  •         public void run() {



  •                 for (int i = 1; i <= 100; i++) {



  •                         // try {



  •                         // Thread.currentThread().sleep(1000);



  •                         // } catch (InterruptedException e) {



  •                         // // TODO Auto-generated catch block



  •                         // e.printStackTrace();



  •                         // }



  •                         System.out.println(Thread.currentThread().getName() + ":"



  •                                         + Thread.currentThread().getPriority() + ":" + i);



  •                 }



  •         }



  • }







  • public class TestThread1 {



  •         public static void main(String[] args) {







  •                 SubThread1 st1 = new SubThread1();



  •                 st1.setName("子线程1");



  •                 st1.setPriority(Thread.MAX_PRIORITY);



  •                 st1.start();



  •                 Thread.currentThread().setName("========主线程");



  •                 for (int i = 1; i <= 100; i++) {



  •                         System.out.println(Thread.currentThread().getName() + ":"



  •                                         + Thread.currentThread().getPriority() + ":" + i);



  •                         // if(i % 10 == 0){



  •                         // Thread.currentThread().yield();



  •                         // }



  •                         // if(i == 20){



  •                         // try {



  •                         // st1.join();



  •                         // } catch (InterruptedException e) {



  •                         // // TODO Auto-generated catch block



  •                         // e.printStackTrace();



  •                         // }



  •                         // }



  •                 }



  •                 System.out.println(st1.isAlive());



  •         }



  • }



优先级改变的仅仅是概率 ,并不是优先全部执行完毕。

创建多线程的方法一:继承Thread类

三个线程的火车票抢票程序。存在线程的安全问题




  • //模拟火车站售票窗口,开启三个窗口售票,总票数为100张



  • //存在线程的安全问题



  • class Window extends Thread {



  •         static int ticket = 100;







  •         public void run() {



  •                 while (true) {



  •                         if (ticket > 0) {



  •                                 System.out.println(Thread.currentThread().getName() + "售票,票号为:"



  •                                                 + ticket--);



  •                         } else {



  •                                 break;



  •                         }



  •                 }



  •         }



  • }







  • public class TestWindow {



  •         public static void main(String[] args) {



  •                 Window w1 = new Window();



  •                 Window w2 = new Window();



  •                 Window w3 = new Window();







  •                 w1.setName("窗口1");



  •                 w2.setName("窗口2");



  •                 w3.setName("窗口3");







  •                 w1.start();



  •                 w2.start();



  •                 w3.start();











  •         }







  • }


static 为了能够让  三个线程共用。

创建多线程的方法二:通过实现的方式
/* * 创建多线程的方式二:通过实现的方式 *  * 对比一下继承的方式 vs 实现的方式 * 1.联系:public class Thread implements Runnable * 2.哪个方式好?实现的方式优于继承的方式 *    why?  1 避免了java单继承的局限性 *          2 如果多个线程要操作同一份资源(或数据),更适合使用实现的方式 */

1 避免局限性:  比如一个学生类实现Runnable接口,多个学生的话代码冗余,而且如果学生继承了人的话,无法再去继承

2



  • //使用实现Runnable接口的方式,售票



  • /*



  • * 此程序存在线程的安全问题:打印车票时,会出现重票、错票



  • */







  • class Window1 implements Runnable {



  •         int ticket = 100;







  •         public void run() {



  •                 while (true) {



  •                         if (ticket > 0) {



  • //                                try {



  • //                                        Thread.currentThread().sleep(10);



  • //                                } catch (InterruptedException e) {



  • //                                        // TODO Auto-generated catch block



  • //                                        e.printStackTrace();



  • //                                }



  •                                 System.out.println(Thread.currentThread().getName() + "售票,票号为:"



  •                                                 + ticket--);



  •                         } else {



  •                                 break;



  •                         }



  •                 }



  •         }



  • }







  • public class TestWindow1 {



  •         public static void main(String[] args) {



  •                 Window1 w = new Window1();



  •                 Thread t1 = new Thread(w);



  •                 Thread t2 = new Thread(w);



  •                 Thread t3 = new Thread(w);







  •                 t1.setName("窗口1");



  •                 t2.setName("窗口2");



  •                 t3.setName("窗口3");







  •                 t1.start();



  •                 t2.start();



  •                 t3.start();



  •         }



  • }


与上面的一个程序相比,多个线程共用一个对象,即共享对象。


下面代码中   Thread 的构造器要求传入一个Runnable对象

实际传的是PrintNum1,  是多态的一种体现。



  • //1.创建一个实现了Runnable接口的类



  • class PrintNum1 implements Runnable {



  •         //2.实现接口的抽象方法



  •         public void run() {



  •                 // 子线程执行的代码



  •                 for (int i = 1; i <= 100; i++) {



  •                         if (i % 2 == 0) {



  •                                 System.out.println(Thread.currentThread().getName() + ":" + i);



  •                         }



  •                 }



  •         }



  • }







  • public class TestThread1 {



  •         public static void main(String[] args) {



  •                 //3.创建一个Runnable接口实现类的对象



  •                 PrintNum1 p = new PrintNum1();



  • //                p.start();



  • //                p.run();



  •                 //要想启动一个多线程,必须调用start()



  •                 //4.将此对象作为形参传递给Thread类的构造器中,创建Thread类的对象,此对象即为一个线程



  •                 Thread t1 = new Thread(p);



  •                 //5.调用start()方法:启动线程并执行run()



  •                 t1.start();//启动线程;执行Thread对象生成时构造器形参的对象的run()方法。







  •                 //再创建一个线程



  •                 Thread t2 = new Thread(p);



  •                 t2.start();



  •         }



  • }


底层原理:

调用  thread类里面的 run方法 执行当前对象的run方法


在构造器传入的时候给target 赋值,所以调用的run方法是传入的对象的run方法


【转载】https://blog.csdn.net/qq_41517071/article/details/81608368


3 个回复

倒序浏览
回复 使用道具 举报
回复 使用道具 举报
奈斯
回复 使用道具 举报
您需要登录后才可以回帖 登录 | 加入黑马