java多线程学习

线程简介

//Process 进程
//Thread 线程

线程创建

      /*
	三种创建方式
        1. Thread class(继承Thread类)
        2. Runnable接口(实现Runnable接口)
        3. Callable接口(实现Callable接口)
    */
    
    //1.创建线程方式一:继承Thread类,重写run()方法,调用start开启线程
    public testThread1 extends Thread{
        public class Test1 extends Thread {
    
        @Override
        public void run() {
            //run方法线程体 
            for (int i = 0; i < 200; i++) {
                System.out.println(i + "A线程执行!");
            }
    
        }
    
        public static void main(String[] args) {
            //main线程,主线程
    
            //创建一个线程对象
            Test1 testThread1 = new Test1();
            //调用start方法开启线程
            testThread1.start();
    
            for (int i = 0; i < 1000; i++) {
                System.out.println(i + "main线程执行!");
            }
        }
    }
    
    //2.创建线程方式二:实现runnable接口,重写run方法,执行线程需要丢入runnable接口实现类,调用start方法
    public class Test3 implements Runnable {
        @Override
        public void run() {
            for (int i = 0; i < 200; i++) {
                System.out.println("B线程执行!");
            }
        }
    
        public static void main(String[] args) {
            //创建runnable接口的实现类对象
            Test3 test3 = new Test3();
    
            //创建线程对象,通过线程对象来开启我们的线程,代理
            //Thread thread = new Thread();
            //thread.start();
    
             //创建代理类对象并启动
            new Thread(test3).start();
    
            for (int i = 0; i < 1000; i++) {
                System.out.println("main线程执行!");
            }
        }
    
    /*3.创建线程方式三:
        1.实现Callable接口,需要返回值类型
        2.重写call方法,需要抛出异常
        3.创建目标对象
        4.创建执行服务:ExecutorService ser = Executors.newFixedThreadPool(1);
        5.提交执行: Future<Boolean> result1 = ser.submit(t1);
        6.获取结果: boolean r1 = result1.get();
        7.关闭服务: ser.shutdownNow();
    */
    
    /*
    PS.静态代理模式总结  
        真实对象和代理对象都要实现同一接口
        代理对象要代理真实角色
    
        好处:1代理对象可以做很多真实对象做不了的事情
             2真实对象专注做自己的事情
    */
  • 线程终止

    /*
    1.建议线程正常停止——>利用次数,不建议死循环
    2.建议使用标志位——>设置一个标志位
    3.不要使用stop或destroy等或者JDK不建议使用的方法
    */
    package TestThread.Test9;
    
    public class TestStop implements Runnable {
    
        private boolean flag = true;//使用标识位来控制线程的停止
    
        @Override
        public void run() {
            int i = 0;
            while (flag) {
                System.out.println("Thread2 run number:" + i++);
            }
        }
    
        public void stop(){ 
            this.flag = false;
        }
    
        public static void main(String[] args) {
            TestStop testStop = new TestStop();
            new Thread(testStop).start();
            for (int i = 0; i < 600; i++) {
                System.out.println("main thread in " + i);
                if(i == 500){
                    testStop.stop();
                    System.out.println("Thread2 over");
                }
    
            }
        }
    
    }
    
  • 线程休眠

    /*
    1.sleep(时间)指定当前线程阻塞的毫秒数
    2.sleep存在异常InterruptedException
    3.sleep时间达到后线程进入就绪状态
    4.可以模拟网络延时,倒计时等
    5.每一个对象都有一个锁,sleep不会释放锁
    */
    //模拟网络延时的作用:放大问题的发生性
    
  • 线程礼让

    //礼让线程,让当前正在执行的线程暂停,但不阻塞
    //将线程从运行状态转为就绪状态
    //让cpu重新调度,礼让不一定成功
    package TestThread.Test10;
    
    public class TestYield {
        public static void main(String[] args) {
            MyYield myYield = new MyYield();
            new Thread(myYield,"a").start();
            new Thread(myYield,"b").start();
        }
    
    }
    class MyYield implements Runnable{
        @Override
        public void run() {
            System.out.println(Thread.currentThread().getName() + "线程开始执行");
            Thread.yield();
            System.out.println(Thread.currentThread().getName() + "线程结束执行");
        }
    }
    
    
  • Lambda表达式

    /*Functional Interface(函数式接口)
    	函数式接口的定义:
    		1.任何接口,如果只包含唯一一个抽象方法,那么它就是一个函数式接口
    			public interface Ruunable {
    				public abstract void run();
    			}
    			
    		2.对于函数式接口,我们可以通过lambda表达式来创建该接口的对象
    
    */
    like = ()->{
        System.out.println("I like lambda5");
    }; 
    like.lambda();
    
    //可以在()内加上参数
    like2 = (int a)->{
        System.out.println(a);
    }; 
    like2.lambda(2);
    
    //可以将参数类型去掉,只有一个参数时可以将()省略
    like2 = a->{
        System.out.println(a);
    }; 
    like2.lambda(2);
    
  • 并发初步

    //问题:多个线程操作同一个资源的情况下,线程不安全,数据紊乱
    //eg.
    public class Test4 implements Runnable{
        private int ticketNum = 10;
        @Override
        public void run() {
            //模拟延迟
            while(ticketNum > 0){
                try {
                    Thread.sleep(20);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                System.out.println(Thread.currentThread().getName() + "-->拿到了第" + ticketNum-- + "票");
            }
        }
    
        public static void main(String[] args) {
            Test4 ticket = new Test4();
            new Thread(ticket, "小明").start();
            new Thread(ticket, "小花").start();
            new Thread(ticket, "小亮").start();
        }
    }
    //出现多个人获得同张票的情况,且出现了第0张 
    
posted @ 2021-03-03 22:59  NoahQue  阅读(46)  评论(0)    收藏  举报