复习(基础1):多线程

1.多线程的创建

(1)继承Thread类

public class MyThread extends Thread{
    @Override
    public void run(){
        for (int i = 0; i < 5; i++) {
            System.out.println("子线程执行次数:"+i);
        }
    }
}

 

/*
多线程的创建方式1:继承Thead类的实现
 */
public class ThreadDemo1 {
    public static void main(String[] args) {
        //new一个新线程对象
        Thread t = new MyThread();
        //调用start方法启动线程(执行的还是run方法)
        t.start();

        for (int i = 0; i < 5; i++) {
            System.out.println("主线程执行输出:"+i);
        }

    }
}

 

 

 

(2)实现Runnable接口

public class MyThreadDemo2 implements Runnable{

    @Override
    public void run() {
        for (int i = 0; i < 5; i++) {
            System.out.println("子线程执行输出:"+i);
        }
    }
}

 

    public static void main(String[] args) {
        //创建任务对象
        Runnable runnable = new MyThreadDemo2();
        //把任务对象交给Thread处理
        Thread t = new Thread(runnable);
        //启动线程
        t.start();
    }

 

(3)JDK5.0提供了Callable和FutrueTask来实现

 

 

public class MyThreadDemo3 implements Callable<String> {
    private int n;
    public MyThreadDemo3(int n){
        this.n = n;
    }
    @Override
    public String call() throws Exception {
        int sum = 0;
        for (int i = 1; i <= n ; i++) {
            sum += i;
        }
        return "子线程执行的结果是:"+sum;
    }
}
public class ThreadDemo3 {
    public static void main(String[] args){
        Callable<String> call = new MyThreadDemo3(100);

        FutureTask<String> futureTask = new FutureTask<>(call);

        Thread t = new Thread(futureTask);

        t.start();
        

        try {
            String s1 = futureTask.get();
            System.out.println(s1);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}

 三种方法对比

2.Thread类的常用方法

 

 

 

3.线程安全

package com.itwpf.d3_thread_safe;

public class ThreadDemo {
    public static void main(String[] args) {
        Account account = new Account("id_card_01",10000);
        new DrawThread(account,"小红").start();
        new DrawThread(account,"小明").start();


    }
}


package com.itwpf.d3_thread_safe;

public class Account {
    private String id;
    private double money;

    public Account() {
    }

    public Account(String id, double money) {
        this.id = id;
        this.money = money;
    }

    public String getId() {
        return id;
    }

    public void setId(String id) {
        this.id = id;
    }

    public double getMoney() {
        return money;
    }

    public void setMoney(double money) {
        this.money = money;
    }

    @Override
    public String toString() {
        return "Account{" +
                "id='" + id + '\'' +
                ", money=" + money +
                '}';
    }

    public void drawMoney(double money) {
        String name = Thread.currentThread().getName();
        if(this.money>=money){
            System.out.println(name+"来取钱,吐出"+money);
            this.money -= money;
            System.out.println("最后剩余:"+this.money);
        }else{
            System.out.println("余额不足");
        }
    }
}



package com.itwpf.d3_thread_safe;

public class DrawThread extends Thread{

    private Account acc;
    public DrawThread(Account acc){
        this.acc = acc;
    }

    public DrawThread(Account acc, String name) {
        super(name);
        this.acc = acc;
    }

    @Override
    public void run() {
        acc.drawMoney(10000);
    }
}

 

4.线程同步

 

(1)加锁方式1:同步代码块

 

    //在类Account的核心方法drawMony中加锁

    public void drawMoney(double money) {
        String name = Thread.currentThread().getName();
        synchronized(this){
            if(this.money>=money){
                System.out.println(name+"来取钱,吐出"+money);
                this.money -= money;
                System.out.println("最后剩余:"+this.money);
            }else{
                System.out.println("余额不足");
            }

        }

    }

 

(2)加锁方式2:同步方法

 

 

    public synchronized void drawMoney(double money) {
        String name = Thread.currentThread().getName();
        if(this.money>=money){
            System.out.println(name+"来取钱,吐出"+money);
            this.money -= money;
            System.out.println("最后剩余:"+this.money);
        }else{
            System.out.println("余额不足");
        }
    }

(3)加锁方式3:Lock锁

 

public void drawMoney(double money) {
        String name = Thread.currentThread().getName();

        lock.lock();//上锁
        try{
            if(this.money>=money){
                System.out.println(name+"来取钱,吐出"+money);
                this.money -= money;
                System.out.println("最后剩余:"+this.money);
            }else{
                System.out.println("余额不足");
            }
        }finally {
            lock.unlock();//解锁
        }
    }

5.线程通信

 

package com.itheima.d7_thread_comunication;

/**
   呼叫系统。
 */
public class CallSystem {
    // 定义一个变量记录当前呼入进来的电话。
    public static int number = 0; // 最多只接听一个。

    /* 接入电话
     */
    public synchronized static void call() {
        try {
            number++;
            System.out.println("成功接入一个用户,等待分发~~~~");

            // 唤醒别人 : 1个
            CallSystem.class.notify();
            // 让当前线程对象进入等待状态。
            CallSystem.class.wait();

        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }

    /**
       分发电话
     */
    public synchronized static void receive() {
        try {
            String name = Thread.currentThread().getName();
            if(number == 1){
                System.out.println(name + "此电话已经分发给客服并接听完毕了~~~~~");
                number--;
                // 唤醒别人 : 1个
                CallSystem.class.notify();
                CallSystem.class.wait(); // 让当前线程等待
            }else {
                // 唤醒别人 : 1个
                CallSystem.class.notify();
                CallSystem.class.wait(); // 让当前线程等待
            }
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }
}
package com.itheima.d7_thread_comunication;

public class CallThread extends Thread{
    @Override
    public void run() {
        // 不断的打入电话
        while (true){
            CallSystem.call();
        }
    }
}
package com.itheima.d7_thread_comunication;

/**
   接电话线程类
 */
public class ReceiveThread extends Thread{
    @Override
    public void run() {
        // 1号  2号
        while (true){
            CallSystem.receive();
        }
    }
}
package com.itheima.d7_thread_comunication;

public class TestDemo {
    public static void main(String[] args) {
        // 1、生产者线程:负责不断接收打进来的电话
        CallThread call = new CallThread();
        call.start();

        // 2、消费者线程:客服,每个客服每次接听一个电话
        ReceiveThread r1 = new ReceiveThread();
        r1.start();
    }
}

6.线程池

(1)概述

 

 

(2)常用API、参数说明

 

ExecutorService pool = new ThreadPoolExecutor(
                3,
                5,
                6,
                TimeUnit.SECONDS,
                new ArrayBlockingQueue<>(5),
                Executors.defaultThreadFactory(),
                new ThreadPoolExecutor.AbortPolicy() );

 

 

(3)线程池处理Runnable任务

 

        ExecutorService pool = new ThreadPoolExecutor(
                3,
                5,
                6,
                TimeUnit.SECONDS,
                new ArrayBlockingQueue<>(5),
                Executors.defaultThreadFactory(),
                new ThreadPoolExecutor.AbortPolicy() );

        pool.execute(new MyRunnable());


结果
pool-1-thread-1子线程0
pool-1-thread-1子线程1
pool-1-thread-1子线程2
pool-1-thread-1子线程3
pool-1-thread-1子线程4
本任务已休眠pool-1-thread-1

(4)线程池处理Callable任务

 

ExecutorService pool = new ThreadPoolExecutor(
                3,
                5,
                6,
                TimeUnit.SECONDS,
                new ArrayBlockingQueue<>(5),
                Executors.defaultThreadFactory(),
                new ThreadPoolExecutor.AbortPolicy() );

        //pool.execute(new MyRunnable());

        Future<String> submit0 = pool.submit(new MyCallable(100));
        Future<String> submit1 = pool.submit(new MyCallable(5));
        Future<String> submit2 = pool.submit(new MyCallable(10));
        Future<String> submit3 = pool.submit(new MyCallable(20));
        Future<String> submit4 = pool.submit(new MyCallable(30));
        Future<String> submit5 = pool.submit(new MyCallable(40));
        Future<String> submit6 = pool.submit(new MyCallable(50));
        String rs = submit0.get();
        System.out.println(rs);
        System.out.println(submit1.get());
        System.out.println(submit2.get());
        System.out.println(submit3.get());
        System.out.println(submit4.get());
        System.out.println(submit5.get());
        System.out.println(submit6.get());


结果:
pool-1-thread-1线程返回的结果是:5050(执行1到100)
pool-1-thread-2线程返回的结果是:15(执行1到5)
pool-1-thread-3线程返回的结果是:55(执行1到10)
pool-1-thread-2线程返回的结果是:210(执行1到20)
pool-1-thread-1线程返回的结果是:465(执行1到30)
pool-1-thread-2线程返回的结果是:820(执行1到40)
pool-1-thread-1线程返回的结果是:1275(执行1到50)

(5)Executors工具类实现线程池

 

 

 

7.定时器

 

 

public class TimeDemo1 {
    public static void main(String[] args) {
        //创建定时器
        Timer timer  = new Timer();//定时器本身就是一个线程
        //调用方法,处理定时任务
        timer.schedule(new TimerTask() {
            @Override
            public void run() {
                System.out.println(Thread.currentThread().getName()+"执行A  "+new Date());
            }
        },0,2000);

        timer.schedule(new TimerTask() {
            @Override
            public void run() {
                System.out.println(Thread.currentThread().getName()+"执行B  "+new Date());
            }
        },0,2000);
    }
}

 

public class TimeDemo2 {
    public static void main(String[] args) {
        //创建ScheduledExecutorService线程池,做定时器
        ScheduledExecutorService pool = Executors.newScheduledThreadPool(3);

        //开启定时器任务
        pool.scheduleAtFixedRate(new TimerTask() {
            @Override
            public void run() {
                System.out.println(Thread.currentThread().getName()+"执行输出AAA  "+new Date());
            }
        },0,2, TimeUnit.SECONDS);

        pool.scheduleAtFixedRate(new TimerTask() {
            @Override
            public void run() {
                System.out.println(Thread.currentThread().getName()+"执行输出AAA  "+new Date());
            }
        },0,2, TimeUnit.SECONDS);

        pool.scheduleAtFixedRate(new TimerTask() {
            @Override
            public void run() {
                System.out.println(Thread.currentThread().getName()+"执行输出bbb  "+new Date());
            }
        },0,2, TimeUnit.SECONDS);

        pool.scheduleAtFixedRate(new TimerTask() {
            @Override
            public void run() {
                System.out.println(Thread.currentThread().getName()+"执行输出ccc  "+new Date());
            }
        },0,2, TimeUnit.SECONDS);

        pool.scheduleAtFixedRate(new TimerTask() {
            @Override
            public void run() {
                System.out.println(Thread.currentThread().getName()+"执行输出ddd  "+new Date());
            }
        },0,2, TimeUnit.SECONDS);
    }
}

8.生命周期

 

 

 

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值