【Java多线程】多线程和线程池

线程创建

继承Thread

public class DemoThread extends Thread{
    @Override
    public void run() {
        for (int i = 0; i < 50; i++) {
            try {
                Thread.sleep(50);
            } catch (InterruptedException e) {
                throw new RuntimeException(e);
            }
            System.out.println(i+" "+Thread.currentThread().getName());
        }
    }
    public static void main(String[] args) {
        DemoThread t1 = new DemoThread();
        DemoThread t2 = new DemoThread();
        t1.start();
        t2.start();
    }
}

实现Runnable接口

public class DemoRunable implements Runnable{
    @Override
    public void run() {
        for (int i = 0; i < 50; i++) {
            try {
                Thread.sleep(50);
            } catch (InterruptedException e) {
                throw new RuntimeException(e);
            }
            System.out.println(i+" "+Thread.currentThread().getName());
        }
    }

    public static void main(String[] args) {
        Thread t = new Thread(new DemoThread(),"worker-1");
        Thread t2 = new Thread(new DemoThread(),"worker-2");
        t.start();
        t2.start();
    }
}

实现Callable接口

public class DemoCallable implements Callable {
    @Override
    public Integer  call() throws Exception {
        int i ,sum=0;
        for ( i=1; i <=50; i++) {
            try {
                Thread.sleep(50);
            } catch (InterruptedException e) {
                throw new RuntimeException(e);
            }
            sum+=i;
            System.out.println(i+" "+Thread.currentThread().getName());
        }
        return sum;
    }

    public static void main(String[] args) throws ExecutionException, InterruptedException {
        FutureTask<Integer> task = new FutureTask<Integer>(new DemoCallable());
        new Thread(task).start();
        System.out.println(task.get()); //获取call返回值
    }
}

买票实现

package thread_prac;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;

public class SellTicket implements Runnable {
    int t = 100;
    Lock lock = new ReentrantLock();
    @Override
    public void run() {

        while (t > 0) {
            try {
                Thread.sleep(10);
            } catch (InterruptedException e) {
                throw new RuntimeException(e);
            }

            lock.lock(); 
//            synchronized (this) {
                if (t > 0) {
                    System.out.println("已卖掉第" + t + "张票 " + Thread.currentThread().getName());
                    t--;
                } else {
                    return;
                }
//            }
            lock.unlock();
        }
    }

    public static void main(String[] args) {
        SellTicket sellTicket = new SellTicket();
        Thread t1 = new Thread(sellTicket, "window1");
        Thread t2 = new Thread(sellTicket, "window2");
        Thread t3 = new Thread(sellTicket, "window3");
        Thread t4 = new Thread(sellTicket, "window4");
        t1.start();
        t2.start();
        t3.start();
        t4.start();
    }
}

线程池创建

package thread_prac;

import java.text.DateFormat;
import java.util.Date;
import java.util.concurrent.*;

public class DemoThreadPool {
    public static void main(String[] args) {
/**
* corePoolSize 线程池核心线程大小
* maximumPoolSize 线程池最大线程数量
* keepAliveTime 空闲线程存活时间
* unit 空间线程存活时间单位
* workQueue 工作队列
*  ①ArrayBlockingQueue 基于数组的有界阻塞队列,按FIFO排序。
*  ②LinkedBlockingQuene 基于链表的无界阻塞队列(其实最大容量为Interger.MAX),按照FIFO排序。
*  ③SynchronousQuene 一个不缓存任务的阻塞队列,生产者放入一个任务必须等到消费者取出这个任务。
*  ④PriorityBlockingQueue 具有优先级的无界阻塞队列,优先级通过参数Comparator实现。
* threadFactory 线程工厂
* handler 拒绝策略 、
*  ①CallerRunsPolicy 该策略下,在调用者线程中直接执行被拒绝任务的run方法,除非线程池已经shutdown,则直接抛弃任务
*  ②AbortPolicy 该策略下,直接丢弃任务,并抛出RejectedExecutionException异常。
*  ③DiscardPolicy 该策略下,直接丢弃任务,什么都不做。
*  ④DiscardOldestPolicy 该策略下,抛弃进入队列最早的那个任务,然后尝试把这次拒绝的任务放入队列
*/
        ExecutorService executorService = new ThreadPoolExecutor(2, 5, 1, TimeUnit.SECONDS, new ArrayBlockingQueue<>(2), Executors.defaultThreadFactory(), new ThreadPoolExecutor.AbortPolicy());
        for (int i = 0; i < 7; i++) {
            executorService.execute(new Worker());
        }
        executorService.shutdown();

//      singleThreadPool();
//      cacheThreadPool();
//      fixedThreadPool();
//      scheduleTheadPool();

    }


    public static void singleThreadPool(){
        /**
         * 只有一个线程的线程池
         * 所有任务都保存队列LinkedBlockingQueue中,核心线程数为1,线程空闲时间为0
         * 等待唯一的单线程来执行任务,并保证所有任务按照指定顺序(FIFO或优先级)执行
         */
        ExecutorService executorService = Executors.newSingleThreadExecutor();
        for (int i = 0; i < 5; i++) {
            executorService.execute(new Worker());
        }
        executorService.shutdown();
    }

    public static void cacheThreadPool(){
        /**
         * 当任务超过线程池的线程数则创建新线程 可缓存无界限线程池(Integer.MAX_VALUE)
         * 空闲线程超过60秒自动回收 核心线程数为0
         */
        ExecutorService executorService = Executors.newCachedThreadPool();
        for (int i = 0; i <100; i++) {
            executorService.execute(new Worker());
        }
        executorService.shutdown();
    }

    public static void fixedThreadPool(){
        /**
         * 创建指定大小的线程池 超出的线程会在LinkedBlockingQueue阻塞队列中等待
         * 核心线程数为可以指定 空闲线程为0
         */
        ExecutorService executorService = Executors.newFixedThreadPool(3);
        for (int i = 0; i <6; i++) {
            executorService.execute(new Worker());
        }
        executorService.shutdown();
    }

    public static void scheduleTheadPool(){
        ScheduledExecutorService executorService = Executors.newScheduledThreadPool(3);
//        executorService.schedule(new Worker(),2,TimeUnit.SECONDS); //延迟2秒后执行任务
//        executorService.scheduleAtFixedRate(new Worker(),2,3,TimeUnit.SECONDS); //周期性执行任务 当前任务执行时间大于等于间隔时间,任务执行后立即执行下一次任务。相当于连续执行了。
        //每当上次任务执行完毕后,间隔一段时间执行。不管当前任务执行时间大于、等于还是小于间隔时间,执行效果都是一样的。
        executorService.scheduleWithFixedDelay(new Runnable() {
            @Override
            public void run() {
                long start = new Date().getTime();
                System.out.println("scheduleWithFixedDelay 开始执行时间:" +
                        DateFormat.getTimeInstance().format(new Date()));
                try {
                    Thread.sleep(5000);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                long end = new Date().getTime();
                System.out.println("scheduleWithFixedDelay执行花费时间=" + (end - start) / 1000 + "m");
                System.out.println("scheduleWithFixedDelay执行完成时间:"
                        + DateFormat.getTimeInstance().format(new Date()));
                System.out.println("======================================");
            }
        }, 1, 2, TimeUnit.SECONDS);
    }
}

class Worker implements Runnable {
    @Override
    public void run() {
        System.out.println(Thread.currentThread().getName() + " > 开始办理业务... ");
        System.out.println(Thread.currentThread().getName() + " >> 正在办理" );
        System.out.println(Thread.currentThread().getName() + " >>> 办理结束 ");
    }
}

生产者和消费者模型

  • wait和notify
package thread_prac;

public class DemoWait {
    public static void main(String[] args) {
        Account account = new Account();
        new Thread(()->{
            for (int i = 0; i < 100; i++) {
                try {
                    account.decrement();
                } catch (InterruptedException e) {
                    throw new RuntimeException(e);
                }
            }
        },"C1").start();
        new Thread(()->{
            for (int i = 0; i < 100; i++) {
                try {
                    account.decrement();
                } catch (InterruptedException e) {
                    throw new RuntimeException(e);
                }
            }
        },"C2").start();
        new Thread(()->{
            for (int i = 0; i < 100; i++) {
                try {
                    account.increment();
                } catch (InterruptedException e) {
                    throw new RuntimeException(e);
                }
            }
        },"P").start();
    }
}

class Account{
    public static int  money = 0;
    public synchronized void increment() throws InterruptedException {
        while (money!=0){ //若使用了if 则多个消费者或多个生产者同时运行会产生问题
            this.wait();
        }
        money++;
        System.out.println(Thread.currentThread().getName()+"=>"+money);
        this.notifyAll();
    }

    public synchronized void decrement() throws InterruptedException {
        while (money==0){
            this.wait();
        }
        money--;
        System.out.println(Thread.currentThread().getName()+"=>"+money);
        this.notifyAll();
    }
}
  • await 和signal 这种是随机的
package thread_prac;

import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;

public class DemoAwait {
    public static void main(String[] args) {
        Account2 account = new Account2();
        new Thread(()->{
            for (int i = 0; i < 100; i++) {
                try {
                    account.decrement();
                } catch (InterruptedException e) {
                    throw new RuntimeException(e);
                }
            }
        },"C1").start();
        new Thread(()->{
            for (int i = 0; i < 100; i++) {
                try {
                    account.decrement();
                } catch (InterruptedException e) {
                    throw new RuntimeException(e);
                }
            }
        },"C2").start();
        new Thread(()->{
            for (int i = 0; i < 100; i++) {
                try {
                    account.increment();
                } catch (InterruptedException e) {
                    throw new RuntimeException(e);
                }
            }
        },"P").start();
    }
}

class Account2 {
    public static int money = 0;
    Lock lock = new ReentrantLock();
    Condition condition = lock.newCondition();
    public void increment() throws InterruptedException {
        lock.lock();
        try {
            while (money != 0) {
                condition.await();
            }
            money++;
            System.out.println(Thread.currentThread().getName() + "=>" + money);
            condition.signalAll();
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            lock.unlock();
        }
    }

    public void decrement() throws InterruptedException {
        lock.lock();
        try {
            while (money == 0) {
                condition.await();
            }
            money--;
            System.out.println(Thread.currentThread().getName() + "=>" + money);
            condition.signalAll();
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            lock.unlock();
        }
    }
}
  • Condition精准唤醒 A唤醒B, B唤醒C,C唤醒A
package thread_prac;

import java.util.Date;
import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;

public class DemoOrderSignal {
    public static void main(String[] args) {
        Data  data = new Data();
        new Thread(()->{
            for (int i = 0; i < 10; i++) {
                data.PrintA();
            }
        },"A").start();
        new Thread(()->{
            for (int i = 0; i < 10; i++) {
                data.PrintB();
            }
        },"B").start();
        new Thread(()->{
            for (int i = 0; i < 10; i++) {
                data.PrintC();
            }
        },"C").start();

    }
}
class Data{
    int num = 1;  //1A 2B 3C
    Lock lock = new ReentrantLock();
    Condition condition1 = lock.newCondition();
    Condition condition2 = lock.newCondition();
    Condition condition3 = lock.newCondition();

    public void PrintA(){
        lock.lock();
        try {
        //业务,判断》执行》通知
            while (num!=1){
                condition1.await();
            }
            System.out.println(Thread.currentThread().getName()+"=>A");
            num = 2;
            condition2.signal(); //唤醒B
        }catch (Exception e){
            e.printStackTrace();
        }finally {
            lock.unlock();
        }
    }
    public void PrintB(){
        lock.lock();
        try {
            while (num!=2){
                condition2.await();
            }
            System.out.println(Thread.currentThread().getName()+"=>B");
            num = 3;
            condition3.signal(); //通知其他线程 我完成了
        }catch (Exception e){
            e.printStackTrace();
        }finally {
            lock.unlock();
        }
    }
    public void PrintC(){
        lock.lock();
        try {
            while (num!=3){
                condition3.await();
            }
            System.out.println(Thread.currentThread().getName()+"=>C");
            num =1;
            condition1.signal(); //通知其他线程 我完成了
        }catch (Exception e){
            e.printStackTrace();
        }finally {
            lock.unlock();
        }
    }
}

输出结果

A=>A
B=>B
C=>C
A=>A
B=>B
C=>C
A=>A
B=>B
C=>C
A=>A
B=>B
C=>C
A=>A
B=>B
C=>C
A=>A
B=>B
C=>C
...
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值