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();
    }
}

 

posted @ 2021-01-29 10:39  Anonymity_Zhang  阅读(67)  评论(0编辑  收藏  举报