JAVA多线程3

JAVA多线程 Thread

线程创建

  • Thread(class):继承Thread(重点)

    public class ThreadDome extends Thread{
        @Override
        public void run() {
            //run方法线程体
            for (int i = 0; i < 20; i++) {
                System.out.println("run方法-"+i);
            }
        }
        public static void main(String[] args) {
            ThreadDome threadDome = new ThreadDome();
            threadDome.start();//同时执行
            threadDome.run();//先执行run,再执行main
            //主方法 主线程
            for (int i = 0; i < 200; i++) {
                System.out.println("main方法-"+i);
            }
        }
    }
    
  • Runnable(接口): 实现Runnable接口(重点)推荐使用

    public class RunnableDemo  implements Runnable{
        @Override
        public void run() {
            //run方法线程体
            for (int i = 0; i < 20; i++) {
                System.out.println("run方法-"+i);
            }
        }
        public static void main(String[] args) {
            RunnableDemo runnableDemo = new RunnableDemo();
            new Thread(runnableDemo).start();
            //主方法 主线程
            for (int i = 0; i < 200; i++) {
                System.out.println("main方法-"+i);
            }
        }
    }
    
  • Callable(接口):实现Callable接口(了解)

多个线程操作一个对象

并发线程不安全

public class TicketRunnable implements Runnable {
    //票总数
    private int ticketNums = 10;
    @Override
    public void run() {
        while (true){
            if (ticketNums <=0){
                break;
            }
            try {
                Thread.sleep(200);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            System.out.println(Thread.currentThread().getName()+"---->拿到了第"+ticketNums--+"票");
        }
    }
    public static void main(String[] args) {
        TicketRunnable ticketRunnable = new TicketRunnable();
        new Thread(ticketRunnable,"A").start();
        new Thread(ticketRunnable,"B").start();
        new Thread(ticketRunnable,"C").start();
    }
}

在这里插入图片描述

龟兔赛跑

public class Race implements Runnable {

    //胜利者
    private static  String winner;

    @Override
    public void run() {
        for (int i = 0; i <= 100; i++) {
            if (Thread.currentThread().getName().equals("兔子") && i%10==0){
                try {
                    Thread.sleep(1);//睡觉
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
            boolean flag = gameOver(i);
            if (flag){
                break;
            }
            System.out.println(Thread.currentThread().getName()+"---跑了 "+i+" 步");
        }
    }

    private  boolean gameOver(int steps){
        if (winner !=null){
            return true;
        }else {
            if (steps>=100){
                winner = Thread.currentThread().getName();
                System.out.println("winner is"+winner);
                return true;
            }
        }
        return false;
    }

    public static void main(String[] args) {
        Race race = new Race();
        new Thread(race,"兔子").start();
        new Thread(race,"乌龟").start();
    }
}

Lamda表达式

/*
推导Lamda表达式
 */
public class Lamda {

    //3.静态内部类
    static class LamdaInImpl2 implements LamdaIn{
        @Override
        public void LamdaIn() {
            System.out.println("LamdaIn---2");
        }
    }

    public static void main(String[] args) {
        LamdaIn lamdaIn = new LamdaInImpl();
        lamdaIn.LamdaIn();

        lamdaIn = new LamdaInImpl2();
        lamdaIn.LamdaIn();

        //4.局部内部类
        class LamdaInImpl3 implements LamdaIn{
            @Override
            public void LamdaIn() {
                System.out.println("LamdaIn---3");
            }
        }
        lamdaIn = new LamdaInImpl3();
        lamdaIn.LamdaIn();

        //5.匿名内部类
        lamdaIn = new LamdaIn() {
            @Override
            public void LamdaIn() {
                System.out.println("LamdaIn---4");
            }
        };
        lamdaIn.LamdaIn();

        //6.Lamda
        lamdaIn = ()-> {
             System.out.println("LamdaIn---5");
        };
        lamdaIn.LamdaIn();
    }
}
//1.定义一个函数式接口,一个接口只有一个方法
interface LamdaIn{
    void LamdaIn();
}
//2.实现类
class LamdaInImpl implements LamdaIn{

    @Override
    public void LamdaIn() {
        System.out.println("LamdaIn---1");
    }
}
public class LamdaTest {
    public static void main(String[] args) {
        LamdaE lamda = ()-> {
             System.out.println("LamdaIn---5");
        };
        //只有一个语句时可以去掉花括号
        //LamdaE lamda = ()-> System.out.println("LamdaE");
        lamda.Lamda();
    }
}

interface LamdaE{
    void Lamda();
}

静态代理模式

public class StaticProxy {
    public static void main(String[] args) {
        new ProxyB(new ProxyA()).Proxy();
    }
}

interface Proxy{
    void Proxy();
}

class ProxyA implements Proxy{

    @Override
    public void Proxy() {
        System.out.println("被代理对象执行....");
    }
}

class ProxyB implements Proxy{

    private ProxyA proxyA;

    public ProxyB(ProxyA proxyA) {
        this.proxyA = proxyA;
    }

    @Override
    public void Proxy() {
        before();
        this.proxyA.Proxy();
        after();
    }
    private void before() {
        System.out.println("代理前...");
    }
    private void after() {
        System.out.println("代理后...");
    }
}

线程状态

在这里插入图片描述
在这里插入图片描述

  • 线程方法
    • setPriority(int newPriority) :更改线程优先级
    • static void sleep(long millis):线程休眠
    • void join():等待线程终止
    • static void yield():暂停当前线程,执行其他线程
    • void interrupt():中断线程
    • boolean isAlive():检测线程是否处于活跃状态

线程停止(stop)

不使用已经淘汰的方法

public class Stop implements Runnable{
    private boolean flag = true;
    
    @Override
    public void run() {
        int i = 0 ;
        while (flag){
            System.out.println("Run..." + i++);
        }
    }

    public void stop(){
        this.flag = false;
    }

    public static void main(String[] args) {
        Stop stop = new Stop();
        new Thread(stop).start();
        for (int i = 0; i < 100; i++) {
            System.out.println("main"+i);
            if(i==90){
                stop.stop();
                System.out.println("线程停止...");
            }
        }
    }
}

线程休眠(sleep)

模拟网络延迟,发现问题

Thread.sleep( time );

线程礼让(yield)

礼让不一定成功,取决于cpu

线程强制执行(join)

主线程等待强制执行线程结束后再继续进行

线程优先级(priority)

优先级高不一定先运行,只是运行的概率高

守护线程(daemon)

  • 线程分为用户线程和守护线程
  • 虚拟机必须确保用户线程执行完毕
  • 虚拟机不用等待守护线程执行完毕(后台日志、监控内存、垃圾回收等等…)

线程同步机制

线程同步其实就是一种等待机制,多个需要同时访问的对象进入对象的等待池,等待前面的线程完毕后面再继续,会损失性能,保证了安全性。

  • 队列和锁 -----安全性

  • 锁机制 (synchronize)

  • 不安全案例

    • 买票案例
    • 银行取钱
    • 线程不安全的集合ArrayList(JUC安全CopyOnWriteArrayList)
  • 同步方法以及同步块

    synchronize(锁对象){
        //操作
    }
    
  • 死锁:资源被持有不释放,不强行剥夺

  • Lock锁---->上锁:lock.lock(); 解锁:lock.unlock();

    class A{
        private final ReenTrantLock lock = new ReenTrantLock();
        public void a(){
            lock.lock();
            try{
                //保证安全的代码
            }finally{
            	lock.unlock();
            }
        }
    }
    

线程协作 生产者消费者模式

  • 线程通信

    • wait():表示线程一直等待,知道其他线程通知,与sleep不同,会释放锁
    • wait(long timeout):等待指定毫秒数
    • notify():唤醒一个处于等待状态的线程
    • notifyAll():唤醒同一个对象上所有调用wait()方法的线程
  • 解决方式 —利用缓冲区解决(管程法)

//管程法
public class PC {
    public static void main(String[] args) {
        SynContainer synContainer = new SynContainer();
        new Producer(synContainer).start();
        new Consumer(synContainer).start();
    }
}

//生产者
class Producer extends Thread{
    SynContainer container;

    public Producer(SynContainer container) {
        this.container = container;
    }

    //生产
    @Override
    public void run() {
        for (int i = 0; i < 100; i++) {
            container.push(new Product(i));
            System.out.println("生产了"+ i +"产品");
        }
    }
}

//消费者
class Consumer extends Thread{
    SynContainer container;

    public Consumer(SynContainer container) {
        this.container = container;
    }

    //消费
    @Override
    public void run() {
        for (int i = 0; i < 100; i++) {
            System.out.println("消费了"+ container.pop().id +"产品");
        }
    }
}

//产品
class Product {
     int id;
    public Product(int id) {
        this.id = id;
    }
}

//缓冲区
class SynContainer{
    //容器
    Product[] products = new Product[10];
    int count = 0;
    //生产者放入产品
    public synchronized void push(Product product){
        //如果容器满了,需要消费者消费
        if (count == products.length){
            try {
                this.wait();
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
        //如果没有满则需要生产
        products[count]= product;
        count++;
        //通知消费
        this.notifyAll();
    }

    //消费者消费产品
    public synchronized Product pop(){
        //判断能否消费
        if (count==0){
            //等待生产者生产,消费者等待
            try {
                this.wait();
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
        //如果可以消费
        count--;
        Product product = products[count];
        this.notifyAll();
        return product;
    }
}
  • 解决方式 —利用标志位解决(信号灯法)

    public class PC {
        public static void main(String[] args) {
            Product product = new Product();
            new Producer(product).start();
            new Consumer(product).start();
        }
    }
    
    //生产者
    class Producer extends Thread{
        Product product;
    
        public Producer(Product product) {
            this.product = product;
        }
    
        @Override
        public void run() {
            for (int i = 0; i < 10; i++) {
                this.product.production("西瓜");
            }
        }
    }
    //消费者
    class Consumer extends Thread{
        Product product;
    
        public Consumer(Product product) {
            this.product = product;
        }
    
        @Override
        public void run() {
            for (int i = 0; i < 10; i++) {
                this.product.consumption();
            }
        }
    }
    
    //产品
    class Product {
        String product;
        boolean flag = true;
        //生产
        public synchronized  void production(String product){
            if (!flag){
                try {
                    this.wait();
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
            System.out.println("生产者生产 "+ product);
            this.notifyAll();
            this.product= product;
            this.flag = !this.flag;
        }
    
        //消费
        public synchronized  void consumption(){
            if (flag){
                try {
                    this.wait();
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
            System.out.println("消费了 "+ product);
            this.notifyAll();
            this.flag = !this.flag;
        }
    }
    
  • 线程池

    • ExecutorService和Executor

    • ExecutorService:线程池接口

    • void execute(Runnable command):执行任务,没有返回值

    • Future Submit(Callable task):执行任务,有返回值

    • void shutdown():关闭连接池

    • Executor:工具类、线程池的工厂类,用于创建并返回不同类型的线程池

      public class Pool {
          public static void main(String[] args) {
              //1.创建线程池
              ExecutorService service = Executors.newFixedThreadPool(10);
              service.execute(new MyThread());
              service.execute(new MyThread());
              service.execute(new MyThread());
              service.execute(new MyThread());
              //2.关闭线程池
              service.shutdown();
          }
      }
      
      class MyThread implements Runnable{
          @Override
          public void run() {
              System.out.println(Thread.currentThread().getName());
          }
      }
      
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值