一、创建线程
1、继承thread类,重新写run方法
public class Test_CreateThread extends Thread {@Overridepublic void run() {//重写run方法 run方法线程体for (int i = 0; i < 500; i++) {System.out.println("我在看视频->"+i);}}public static void main(String[] args) {Test_CreateThread test_createThread=new Test_CreateThread();//test_createThread.start();test_createThread.run();//main主线程体for (int i = 0; i < 500; i++) {System.out.println("我在学习多线程->"+i);}}}
2、实现Runnable接口,重写run方法 使用Thread代理
public class Test_CreateThread2 implements Runnable {@Overridepublic void run() {//run方法线程体for (int i = 0; i < 5; i++) {System.out.println("我在看视频->" + i);}}public static void main(String[] args) {Test_CreateThread2 test_createThread2 = new Test_CreateThread2();// Thread thread=new Thread(test_createThread2);// thread.start();new Thread(test_createThread2).start();for (int i = 0; i < 5; i++) {System.out.println("我在学习->"+i);}}}
注意:
启动线程的方法不同,调用run()方法时,如果子线程在主线程体之前启动,则会先运行子线程,然后才会执行主线程体语句。
调用start()方法时线程不一定立即执行,由cpu安排调度,就会出现交替执行的情况。如下图
二、Lambda表达式 推导
1、外部类
public class Test_Lambda {//调用public static void main(String[] args) {IRead iRead=new Read();iRead.read();}}//1、定义一个函数式接口interface IRead{void read();}//2、实现类 外部类class Read implements IRead{@Overridepublic void read() {System.out.println("I read book1!");}}
外部类修饰符:只能用public、abstract、final修饰
2、静态内部类
public class Test_Lambda {//2、实现类 内部类static class Read implements IRead {@Overridepublic void read() {System.out.println("i read book2");}}public static void main(String[] args) {IRead iRead = new Read();iRead.read();}}//1、函数式接口interface IRead {void read();}
静态内部类必须加static修饰
内部类修饰符:private、protected、public、final、static、abstract
3、局部内部类
public class Test_Lambda {public static void main(String[] args) {//2、实现类 局部内部类class Read implements IRead{@Overridepublic void read() {System.out.println("i read book3!");}}IRead iRead = new Read();iRead.read();}}//1、函数式接口interface IRead {void read();}
4、匿名内部类
public class Test_Lambda {public static void main(String[] args) {//2、实现类 匿名内部类new IRead() {@Overridepublic void read() {System.out.println("i read book4!");}}.read();}}//1、函数式接口interface IRead {void read();}
5、lambda表达式
public class Test_Lambda {public static void main(String[] args) {//2、lambda表达式IRead read = () -> {System.out.println("i read book5!");};read.read();}}//1、函数式接口interface IRead {void read();}
- lambda表达式主体只有一句时,{}可以省略
IRead read = () -> System.out.println("i read book5!");
- 参数类型可以省略 有多个参数时,要省略参数类型就必须全部省略
//IRead read = (int a) -> System.out.println("i read book5!->"+a);IRead read =(a) -> System.out.println("i read book5!->"+a);
- 只有一个参数时,()可以省略
IRead read =a-> System.out.println("i read book5!->"+a);
三、线程优先级
- 线程的优先级值为从1-10的整数,越大则优先级越大。若超出1-10这个范围,就会抛出异常
- 优先级只能表示线程先执行的可能性越大,但也会出现低优先级先执行的情况。得看cpu调度的心情
- main主线程的优先级固定不变,为5
public class Test_Priority {public static void main(String[] args) {//打印主线程的优先级System.out.println(Thread.currentThread().getName()+"-> "+Thread.currentThread().getPriority());TestPriority tp=new TestPriority();Thread t1=new Thread(tp);Thread t2=new Thread(tp);Thread t3=new Thread(tp);Thread t4=new Thread(tp);Thread t5=new Thread(tp);//设置优先级 并启动t1.start();t2.setPriority(1);t2.start();t3.setPriority(5);t3.start();t4.setPriority(10);t4.start();t5.setPriority(8);t5.start();}}class TestPriority implements Runnable{@Overridepublic void run() {System.out.println(Thread.currentThread().getName()+"-> "+Thread.currentThread().getPriority());}}
四、线程的同步 synchronized
1、synchronized方法
- synchronized方法控制对 对象 的访问,每个对象都有一把锁。
- 添加了synchronized方法后,每个线程调用对象时都需要获得对象的锁,获得之后才能执行,且一直独占对象的锁,直到方法执行完后才会释放,后续线程才能获得这个锁。
- 方法声明为synchronized会影响效率
public class Test_synchronized {public static void main(String[] args) {buyTickets buyTickets=new buyTickets();new Thread(buyTickets,"小帆").start();new Thread(buyTickets,"小卿").start();new Thread(buyTickets,"小陈").start();}}class buyTickets implements Runnable {private int ticketNum = 10; //票的总数boolean flag = true; //线程停止标志@Overridepublic void run() {while (flag){try {buy();} catch (InterruptedException e) {e.printStackTrace();}}}//添加synchronized 同步方法 锁的是buyTickets对象private synchronized void buy() throws InterruptedException {if(ticketNum<=0){flag=false; //票总数为0时,线程结束return;}Thread.sleep(100); //模拟延时,放大问题发生性System.out.println(Thread.currentThread().getName()+"买到了第"+ticketNum-- +"张票");}}
如果不添加synchronized方法锁,就会出现买到负数的票和多人买到同一张票的情况。如下图:
添加synchronized方法后的运行结果如下:
