b站 尚硅谷 JavaSE教程:https://www.bilibili.com/video/BV1Kb411W75N?p=415 ~ https://www.bilibili.com/video/BV1Kb411W75N?p=429
1 多线程概述
2 Java中线程的创建和使用
-
/** * 多线程的创建 * 方式一:继承于Thread类 * 1、创建一个继承于Thread类的子类 * 2、重写Thread类的run(),将此线程执行的操作声明在run()中 * 3、创建Thread类的子类对象 * 4、通过此对象调用start():启动当前线程;调用当前线程的run()方法 * */ class MyThread extends Thread{ @Override public void run() { for(int i = 0; i < 100; i++){ if(i % 2 == 0){ System.out.println(Thread.currentThread().getName() + ":" + i); } } } } class MyThread1 extends Thread{ @Override public void run() { for(int i = 0; i < 100; i++){ if(i % 2 != 0){ System.out.println(Thread.currentThread().getName() + ":" + i); } } } } public class ThreadTest { public static void main(String[] args) { // MyThread t1 = new MyThread(); // t1.start(); // //问题一:不能通过直接调用run()的方式启动线程,此时只相当于在main()中调用了方法,仍然是主线程 // //t1.run(); // //问题二:再启动一个线程,遍历100以内的偶数, // // 不可以让已经start()的线程去执行,会报IllegalThreadStateException异常 // //需要重新创建一个线程的对象 // MyThread1 t2 = new MyThread1(); // t2.start(); //创建Thread类的匿名子类的方式 new Thread(){ @Override public void run() { for(int i = 0; i < 100; i++){ if(i % 2 != 0){ System.out.println(Thread.currentThread().getName() + ":" + i); } } } }.start(); new Thread(){ @Override public void run() { for(int i = 0; i < 100; i++){ if(i % 2 == 0){ System.out.println(Thread.currentThread().getName() + ":" + i); } } } }.start(); new Thread(() -> { for(int i = 0; i < 100; i++){ if(i % 2 == 0){ System.out.println(Thread.currentThread().getName() + ":" + i); } } }).start(); } }
-
package Thread; /** * 测试Thread类中的常用方法: * 1、start():启动当前线程;调用当前线程的run() * 2、run():通常需要重写Thread类的此方法,将创建的线程要执行的操作声明在此方法中 * 3、currentThread():静态方法,返回执行当前代码的线程 * 4、getName():获取当前线程的名字 * 5、setName():设置当前线程的名字 * 6、yield():释放当前CPU的执行权 * 7、join():在线程a中调用线程b的join(),此时线程a就进入阻塞状态,直到线程b完全执行完后,线程a才结束阻塞状态 * 8、stop():已过时。当执行此方法时,强制结束当前线程 * 9、sleep(long millitime):让当前线程“睡眠”指定的millitime毫秒,在指定的millitime毫秒时间内,当前线程是阻塞状态 * 10、isAlive():判断当前线程是否存活 * * 线程的优先级 * NORM_PRIORITY :5 默认 * MIN_PRIORITY :1 * MAX_PRIORITY :10 * getPriority():获取线程的优先级 * setPriority(int P):设置线程的优先级 * 高优先级的线程要抢占低优先级线程的CPU执行权,但是只是从概率上讲,高优先级的线程 * 高概率地被执行,并不意味着只有当高优先级的进程执行完后,低优先级的进程才执行 */ class HelloThread extends Thread{ @Override public void run() { for(int i = 0; i < 100; i++){ if(i % 2 == 0){ //此时不能将异常直接throws,因为run()方法是继承自Thread, // 而在Thread中的run()方法并未throws异常 try { sleep(10); } catch (InterruptedException e) { e.printStackTrace(); } System.out.println(Thread.currentThread().getName() + ":" +Thread.currentThread().getPriority() +":"+ i); } // if(i % 20 == 0){ // this.yield(); // Thread.currentThread().yield(); // } } } //除了通过set方法设置线程名,也可以通过构造器的方法 public HelloThread(String name){ super(name); } } public class ThreadMethodTest { public static void main(String[] args) { HelloThread h1 = new HelloThread("线程1"); //h1.setName("thread==1"); h1.setPriority(Thread.MAX_PRIORITY); h1.start(); //给主线程命名 Thread.currentThread().setName("主线程"); for(int i = 0; i < 100; i++){ if(i % 2 == 0){ System.out.println(Thread.currentThread().getName() + ":" +Thread.currentThread().getPriority() +":"+ i); } if(i == 20){ try { h1.join(); } catch (InterruptedException e) { e.printStackTrace(); } } } System.out.println(h1.isAlive()); } }
- static 变量系统共享一个
- 一个w对象放入三个构造器中,三个线程都是使用同一个ticket变量
-
package Thread; /** * 创建多线程的方式二:实现Runnable接口 * 1、创建一个实现了Runnable接口的类 * 2、实现类去实现Runnable中的抽象方法:run() * 3、创建实现类的对象 * 4、将此对象作为参数传递到Thread类的构造器中,创建Thread类的对象 * 5、通过Thread类的对象调用start():启动线程;调用当前线程的run()-->调用了Runnable类型的target的run()方法 * * 比较创建线程的两种方式: * Java是单继承的,如果一个类已经显式地有了父类,那么其将无法再继承Thread类 * 实现Runnable接口的多线程创建方式,天然地实现了数据的共享 * 在开发中:优先选择实现Runnable接口的方式 * 原因:1、实现的方式没有类的单继承性的局限性 * 2、实现的方式更适合来处理多个线程有共享数据的情况 * 联系:Thread类本身实现了Runnable接口 * 相同点:两种方式都需要重写run(),将线程要执行的逻辑声明在run()中 */ class MThread implements Runnable{ @Override public void run() { for (int i = 0; i < 100; i++) { if(i % 2 == 0){ System.out.println(Thread.currentThread().getName() +":"+i); } } } } public class ThreadTest1 { public static void main(String[] args) { MThread mThread = new MThread(); Thread t1 = new Thread(mThread); t1.start(); //再启动一个线程 Thread t2 = new Thread(mThread); t2.start(); } }
- 用户线程消亡后,守护线程也自动消亡。