多线程的实现

线程通信的问题

 /*例如: A B C
 *  A--1   	    B--6    		 C--11
 *  A--2    		B--7    		 C--12
 *  A--3   	 	B--8    		 C--13
 *  A--4    		B--9    		 C--14
 *  A--5    		B--10  		 C--15
 *  在回来重新跑
 *  wait();执行该方法,当前线程就会进入线程阻塞,换成其他线程 ,并释放同步监视器
 *  notify();执行该方法,就会唤醒被wait阻塞的一个线程
 *      如果有多个线程wait阻塞了,优先唤醒优先级高的
 *  notifyAll();唤醒所有被wait阻塞的线程
 
 *  说明:都定义在Object类中
 *      上述三个方法都必须在同步代码块或者同步方法中使用
 *      上述三个方法调用者都必须是同步代码块或者同步监视器
 *
 *  sleep和wait有什么异同
 *      相同点:都可以是当前线程进入阻塞状态
 *      不同点:
 *
 *          1.  sleep()属于Thread wait()属于Object
 *          2.  调用者要求不同,sleep在任何位置都可以使用,wait()只能在同步代码块或者同步方法中使用
 *          3.  释放同步监视器:如果两个方法都在同步代码块中调用,
 *                  sleep(),不会释放同步资源
 *                  wait().会释放资源
 *
 */

上代码:


public class ThreadDemo01 {
    public static void main(String[] args) {
        Num n=new Num();
        Thread a=new Thread(n,"A");
        Thread b=new Thread(n,"B");
        Thread c=new Thread(n,"C");

        a.start();
        b.start();
        c.start();
    }
}
//公用的数
class Num implements Runnable{
    int n=0;//计数器
    //每加五次就换一个线程
    @Override
    public void run() {
        while(true){
        show();
        }
    }
    public synchronized void show(){
//        notify();
        //每次执行累加
        n++;
        System.out.println(Thread.currentThread().getName()+"----"+n);
        //n%5==0的时候,就表示当前线程走了5次,需要让当前的线程阻塞,换成其他线程
        if(n%5==0){
            try {
                wait();
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }

    }
}

生产消费者问题:

/**
 * @author DeYou
 * @date 2022/4/1 21:39
 *
 * 生产者消费者模型
 * 生产者生产好的产品交给店员,消费者从店员手中买走产品
 * 假设店员一次只能持有固定数量的产品(20),如果生产者试图产生更多的产品,
 * 店员就会叫生产者停一下,如果由消费者从店员手中买走产品,此时店员手中就有空位置了,生产者就可以继续生产
 * 如果店员手中没有产品,店员就会告诉消费者你等一下,等店员手中有了产品再通知消费者来领取产品
 *
 * 分析:
 *      1.存不存在多线程问题?  存在,生产者线程;消费之线程
 *      2.是否有数据共享问题?  是,产品的数量,店员
 *      3.存不存在过程安全问题? 存在,上保安(上锁)
 */

上代码:


public class ThreadDemo02 {
    public static void main(String[] args) {
        Clerk dd=new Clerk();//店员

        //生产者
        Product sy=new Product(dd);
        sy.setName("十堰");
        Product zy=new Product(dd);
        zy.setName("烛影");

        //消费者
        Consumer ck=new Consumer(dd);
        ck.setName("苍空");
        Consumer tr=new Consumer(dd);
        tr.setName("天日");
        Consumer ft=new Consumer(dd);
        ft.setName("浮屠");
        Consumer hy=new Consumer(dd);
        hy.setName("黑炎");

        //启动
        sy.start();
        zy.start();

        ck.start();
        tr.start();
        ft.start();
        hy.start();

    }

}
//店员
class Clerk{
    //产品数量
    int productCount=0;
    //店员可以要求生产者生产产品
    public synchronized void produceProduct(){
        if(productCount<20){
            notifyAll();//数量小于20的时候,才可以调用生产产品的线程
            productCount++;
            System.out.println(Thread.currentThread().getName()+":开始生产"+productCount+"产品");;
        }else{//如果产品数量大于等于20.让产品生产者等待一下
            try {
                wait();
            } catch (InterruptedException e) {
                e.printStackTrace();
            }

        }

    }
    //店员的消费产品的方法
    public synchronized void consumeProduct(){
        //如果产品数量大于0才可以消费
        if (productCount>0){
            notifyAll();//唤醒
            System.out.println(Thread.currentThread().getName()+":开始消费第"+productCount+"个产品");
            productCount--;
        }else{
            //产品小于等于0,告诉消费者等一下
            try {
                wait();
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }

    }
}
//生产者线程
class Product extends Thread{
    Clerk clerk;
    public Product(Clerk clerk){
        this.clerk=clerk;
    }
    @Override
    public void run(){
        System.out.println(getName()+"厂家开始生产产品------");
        while(true){
            try {
                Thread.sleep(100);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            clerk.produceProduct();//店员开始让生产者生产
        }
    }
}
class Consumer extends Thread{
    Clerk clerk;
    public Consumer(Clerk clerk){
        this.clerk=clerk;
    }
    @Override
    public void run(){
        System.out.println(getName()+"消费者:正在消费产品.......");
        while(true){
            try {
                Thread.sleep(500);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            clerk.consumeProduct();//店员服务消费者消费
        }
    }
}

多线程的实现

/**
 * @author DeYou
 * @date 2022/4/2 18:32
 * java实现
 *  多线程方法一:
 *      继承Thread
 *  多线程方法二:
 *      实现Runnable接口
 *  多线程方法三:
 *      实现Callable接口
 *  多线程方法四:
 *      线程池的方式
 *
 *
 *  实现Callable方式河Runnable方式的优势
 *      1.Call可以有返回值
 *      2.Call可以抛出异常,被外面的调用者捕获异常,从而获取更多的异常信息
 *      3.Callable支持泛型
 */

上代码:


public class ThreadDemo03 {
    public static void main(String[] args) throws ExecutionException, InterruptedException {
        //3.创建Callable实例对象
        CallableTest c=new CallableTest();
        //创建futureTask对象,将上述的CallableTest实例传入构造中
        FutureTask ft=new FutureTask(c);
        //5.创建Thread对象,将上述FutureTask实例传入构造中
        Thread t=new Thread(ft);
        //6.启动线程
        t.start();
        /*
        在call方法返回值是通过FutureTask对象调用get方法获取的
         */
        System.out.println("call方法的返回值是:"+ft.get());

    }
}
//创建一个类实现Callable接口
class CallableTest implements Callable{

    //重写call()
    @Override
    public Object call() throws Exception {
        int sum=0;
        for (int i = 0; i < 100; i++) {
            sum+=i;
        }
        return sum;
    }
}

希望在此你能有不少的收获,如果有错的话,请斧正!

你可能感兴趣的:(java,开发语言,java-ee,学习,intellij-idea)