zoukankan      html  css  js  c++  java
  • java_多线程 (四)

    1.线程通信案例 : 生产者 与 消费者

    //线程通信案例 : 生产者与消费者
    
    /**
     * 注意点 : produceProduct() & customerProduct() 要共享数据所以要改成同步方法
     *          wiat() 要有对应的notify()
     */
    
    //共享数据
    class Clerk{
        private int procudtNum=0;
    
        //生产产品
        public synchronized void produceProduct() {
            if (procudtNum<20){
                procudtNum++;
                System.out.println(Thread.currentThread().getName()+"开始生产产品:"+procudtNum);
                notify();
            }else{
                try {
                    wait();
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        }
        //消费产品
        public synchronized void customerProduct() {
            if (procudtNum>0){
                System.out.println(Thread.currentThread().getName()+"开始消费产品:"+procudtNum);
                procudtNum--;
                notify();
            }else{
                try {
                    wait();
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        }
    }
    //生产者
    class Producer extends Thread{
        private Clerk clerk;
        public Producer(Clerk clerk){
            this.clerk=clerk;
        }
    
        @Override
        public void run() {
            System.out.println(Thread.currentThread().getName()+"开始生产产品..");
            while (true){
                try {
                    sleep(10);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                clerk.produceProduct();
            }
        }
    }
    //消费者
    class Customer extends Thread{
        private Clerk clerk;
        public Customer(Clerk clerk){
            this.clerk=clerk;
        }
    
        @Override
        public void run() {
            System.out.println(Thread.currentThread().getName()+"开始消费产品..");
            while (true){
                try {
                    sleep(10);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                clerk.customerProduct();
            }
        }
    }
    
    public class ProductTest {
        public static void main(String[] args) {
            Clerk clerk = new Clerk();
    
            Producer p1 = new Producer(clerk);
            p1.setName("生产者1");
            Customer c1 = new Customer(clerk);
            c1.setName("消费者1");
    
            p1.start();
            c1.start();
        }
    }

    2. JDK 5 加入了两种创建线程的新方式

     2.1 实现Callable接口

    //第三种创建线程的方式 : Callable
    
    import java.util.concurrent.Callable;
    import java.util.concurrent.ExecutionException;
    import java.util.concurrent.FutureTask;
    
    //1.创建一个实现Callable接口的实现类
    class NewThread implements Callable{
        //2.重写call()方法 , 将此线程具体的代码声明在其中
        @Override
        public Object call() throws Exception {
            int sum=0;
            for (int i = 0; i <= 100; i++) {
                if (i % 2 ==0){
                    System.out.println(i);
                    sum+=i;
                }
            }
            return sum;
        }
    }
    
    public class ThreadNew{
        public static void main(String[] args) {
            //3.创建实现Callable的实现类对象
            NewThread newThread = new NewThread();
            //4.将次实现类作为参数传入FutureTask的构造器中 , 创建FutureFask对象
            FutureTask futureTask = new FutureTask(newThread);
            //5. 启动线程  : 因为FutureFask也是Runnable的实现类 , 所以可以传参
            new Thread(futureTask).start();
            //获取call()的返回值
            try {
                Object i = futureTask.get();
                System.out.println(i);
            } catch (InterruptedException e) {
                e.printStackTrace();
            } catch (ExecutionException e) {
                e.printStackTrace();
            }
        }
    
    }

    2.2 使用线程池

    /*
    创建线程的第四种方式 : 线程池
     */
    
    import java.util.concurrent.ExecutorService;
    import java.util.concurrent.Executors;
    import java.util.concurrent.ThreadPoolExecutor;
    
    class NumberThread implements Runnable{
        @Override
        public void run() {
            for (int i = 0; i <= 100; i++) {
                if (i % 2 ==0){
                    System.out.println(Thread.currentThread().getName()+":"+i);
                }
            }
        }
    }
    
    public class ThreadPool {
        public static void main(String[] args) {
            //1.创建有固定数量的线程池
            ExecutorService service = Executors.newFixedThreadPool(10);
            //设置线程池的属性 , 因为ExecutorService是一个接口 , 所以需要用接口的实现类来设置 : ThreadPoolExecutor
            ThreadPoolExecutor service1 = (ThreadPoolExecutor) service;
            service1.setCorePoolSize(3);
            //service1.setKeepAliveTime();
    
            //2, 适用于Runnable
            service.execute(new NumberThread());
            //适用于Callable , 可以有返回值
            //service.submit();
    
            //3.关闭线程池
            service.shutdown();
        }
    }
  • 相关阅读:
    观察者模式
    饿汉单例模式 and 懒汉单例模式
    解决hash冲突之分离链接法
    bat处理文件
    使用json-org包实现POJO和json的转换
    并发修改异常(ConcurrentModificationException)
    封装特效记录--持续更新
    vue loading组件
    vue授权页面登陆之后返回之前的页面
    vue 路由权限
  • 原文地址:https://www.cnblogs.com/Anonymity-zhang/p/14343635.html
Copyright © 2011-2022 走看看