java多线程06 线程协作 线程通信(管程法,信号灯法) 线程池

线程协作

生产者消费者模式

线程通信

方法名作用
wait()表示线程一直等待,直到其他线程通知,与sleep不同,会释放锁
wait(long timeout)指定等待的毫秒数
notify()唤醒一个处于等待状态的线程
notifyAll()唤醒同一个对象上所有调用 wait() 方法的线程,优先级别高的线程优先调度

注意:均是 Object 类的方法,都只能在同步方法或者同步代码块中使用,否则会抛出异常 IllegalMonitorStateException


解决方式1: 并发协作模型 “ 生产者/消费者模式 ” --> 管程法

  • 生产者:负责生产数据的模块(可能是方法、对象、线程、进程)
  • 消费者:负责处理数据的模块(可能是方法、对象、线程、进程)
  • 缓冲区:消费者不能直接使用生产者的数据,他们之间有个 “缓冲区”

生产者将生产好的数据放入缓冲区,消费者从缓冲区拿出数据


解决方式2: 并发协作模型 “ 生产者/消费者模式 ” --> 信号灯法

true/false


管程法

package basic.lock;

public class TestPC {
    public static void main(String[] args) {
        SynContainer container = new SynContainer();
        new Producer(container).start();
        new Consumer(container).start();
    }
}

// producer
class Producer extends Thread{
    SynContainer container;
    public Producer(SynContainer container){
        this.container = container;
    }

    @Override
    public void run() {
        for (int i = 0; i < 100; i++) {
            container.push(new Chicken(i));
            System.out.println("produce " + i + " chickens");
        }
    }
}

// consumer
class Consumer extends Thread{
    SynContainer container;
    public Consumer(SynContainer container){
        this.container = container;
    }

    @Override
    public void run() {
        for (int i = 0; i < 100; i++) {
            System.out.println("consume "+ container.pop().id +"chicken");
        }
    }
}

// prodcut
class Chicken{
    int id;

    public Chicken(int id) {
        this.id = id;
    }
}

// buffer zone
// container size
// method: producer puts product
// method: consumer consume product
class SynContainer{
    Chicken[] chickens = new Chicken[10]; // buffer
    int count = 0;
    // consume
    public synchronized void push(Chicken chicken){
        if(count==chickens.length){
            try {
                wait();
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
        chickens[count] = chicken;
        count++;
        this.notifyAll();
    }
    // produce
    public synchronized Chicken pop(){
        if(count==0){
            try {
                wait();
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
        count--;
        Chicken chicken = chickens[count];
        this.notifyAll();
        return chicken;
    }
}

信号灯法

package basic.lock;

// signal
// flag
public class TestPC2 {
    public static void main(String[] args) {
        TV tv = new TV();
        new Player(tv).start();
        new Watcher(tv).start();
    }

}

// producer -- actor
class Player extends Thread{
    TV tv;
    public Player(TV tv){
        this.tv = tv;
    }

    @Override
    public void run() {
        for (int i = 0; i < 20; i++) {
            if(i%2==0){
                this.tv.play("happy going");
            }else{
                this.tv.play("bad boy");
            }
        }
    }
}


// consumer -- audience
class Watcher extends Thread{
    TV tv;
    public Watcher(TV tv){
        this.tv = tv;
    }

    @Override
    public void run() {
        for (int i = 0; i < 10; i++) {
            tv.watch();
        }
    }
}

// product -- program
class TV{
    String voice;
    boolean flag = true;

    // act
    public synchronized void play(String voice){
        if(!flag){
            try {
                this.wait();
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
        System.out.println("actor act "+voice);
        this.notifyAll(); // wake up
        this.voice = voice;
        this.flag = !this.flag;
    }

    // watch
    public synchronized void watch(){
        if(flag){
            try {
                this.wait();
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
        System.out.println("watch "+voice);
        // notify
        this.notifyAll();
        this.flag = !this.flag;
    }
}

线程池

经常创建和销毁、使用量特别大的资源,比如并发情况下的线程,对性能影响很大

思路:提前创建好多个线程,放入线程池中,使用时直接获取,使用完放回池中。可以避免频繁创建销毁、实现重复利用

好处:

  • 提高响应速度(减少创建新线程的时间)
  • 降低资源消耗(重复利用线程池中线程,不需要每次都创建)
  • 便于线程管理
    • corePoolSize: 核心池的大小
    • maximumPoolSize: 最大线程数
    • keepAliveTime: 线程没有任务时最多保持多长时间后会终止

线程池相关接口:ExecutorService 和 Executors

ExecutorService 真正的线程池接口,常见子类 ThreadPoolExecutor

  • Void execute(Runnable command): 执行任务/命令,没有返回值,一般用来执行 Runnable
  • Future submit (Callable task): 执行任务,有返回值,一般又来执行 Callable
  • void shutdown():关闭连接池

Executors:工具类、线程池的工厂类,用于创建并返回不同类型的线程池


package basic.lock;

import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

public class  TestPool {
    public static void main(String[] args) {
        // 1, create pool
        // param: size of thread pool
        ExecutorService service = Executors.newFixedThreadPool(10);
        service.execute(new MyThread());
        service.execute(new MyThread());
        service.execute(new MyThread());
        service.execute(new MyThread());
        // close connect
        service.shutdown();

    }
}

class MyThread implements Runnable{
    @Override
    public void run() {
        for (int i = 0; i < 10; i++) {
            System.out.println(Thread.currentThread().getName()+i);
        }
    }
}

线程创建的复习

package basic;

import com.sun.org.apache.bcel.internal.generic.NEW;

import java.util.concurrent.Callable;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.FutureTask;

public class Review {
    public static void main(String[] args) {

        new MyThread1().start();

        new Thread(new MyThread2()).start();

        FutureTask<Integer> futureTask = new FutureTask<Integer>(new MyThread3());
        new Thread(futureTask).start();
        try {
            Integer integer = futureTask.get();
            System.out.println(integer);
        } catch (InterruptedException e) {
            e.printStackTrace();
        } catch (ExecutionException e) {
            e.printStackTrace();
        }
    }
}
class MyThread1 extends Thread{
    @Override
    public void run() {
        System.out.println("1");
    }
}

class MyThread2 implements Runnable{
    @Override
    public void run() {
        System.out.println("2");
    }
}

class MyThread3 implements Callable<Integer>{
    @Override
    public Integer call() throws Exception {
        System.out.println("3");
        return 100;
    }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值