Thread

本文不是深究线程,而是对线程有一个基本的了解。

1、进程与线程

进程是一个执行的程序,是系统进行资源分配的独立单位而线程是该程序的不同执行序列。

            资源                  通讯                  切换            

进程        独占                困难                    开销大

线程     共享                    容易                    开销小

2、线程


2.1创建方式

    继承thread,重写run方法

public class Byextend extends  Thread{

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

    public static void main(String[] args) {
        Byextend b = new Byextend();
        b.setName("继承声明");
        b.start();
        for(int i=0;i<10;i++) {
            System.out.println(Thread.currentThread().getName()+"  "+i);
        }
    }
}

    实现runnalbe接口,重写run方法

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

    public static void main(String[] args) {
        ByImplement byImplement = new ByImplement();
        Thread thread = new Thread(byImplement);
        thread.setName("实现Runnable声明");
        thread.start();
        for(int i=0;i<10;i++) {
            System.out.println(Thread.currentThread().getName()+"  "+i);
        }
    }
}

    实现callable接口,重写call方法(重点是可以有返回值,而且能抛异常)

public class ByCallable implements Callable<String> {    //String指定返回的类型
    @Override
    public String call() throws Exception {
        return "impllements by callable";
    }

    public static void main(String[] args) {
        ByCallable callable = new ByCallable();
        //futureTask用于接受返回值
        FutureTask<String> futureTask = new FutureTask<>(callable);
        Thread thread = new Thread(futureTask);
        thread.start();
        try {
            //futureTask.get()获取返回的值
            System.out.println(futureTask.get());
        } catch (InterruptedException e) {
            e.printStackTrace();
        } catch (ExecutionException e) {
            e.printStackTrace();
        }
    }
}

Executor

以上三种实现方式都是显式的创建一个线程,java给我们提供了一个线程执行器Executor通过使用线程池帮助创建并执行线程

CachedThreadPool

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

    public static void main(String[] args) {
        ExecutorService es = Executors.newCachedThreadPool();
        es.execute(new ByImplement());
        es.shutdown();

    }
}

CachedThreadPool通常会创建与所需数量相同的线程(提高性能),当加入新任务并且不存在可用线程时会创建新的线程提供使用,会回收超过60s未被使用的空闲线程所以节约资源

FixedThreadPool

public class ByImplement  implements  Runnable{  .......线程声明run方法同上
    public static void main(String[] args) {
        ExecutorService es = Executors.newFixedThreadPool(2);
        es.execute(new ByImplement());
        es.shutdown();

    }
}

FixedThreadPool会根据指定参数创建包含一定数量线程的线程池,以后有且只有该数量的线程,如果有新任务加入会等到有空闲线程可用,当某个线程奔溃时会新增一个线程补充。

SingleThreadPool

public class ByImplement  implements  Runnable{  .......线程声明run方法同上
    public static void main(String[] args) {
        ExecutorService es = Executors.newSingleThreadPool();
        es.execute(new ByImplement());
        es.shutdown();

    }
}

SingleThreadPool只有一个线程的线程池,执行任务是有序的,如果该线程出错会有新的线程补充,而FixedThreadPool(1)线程出错不会有新线程补充

使用excute执行实现callable的线程

public class ByCallable implements Callable<String> {
    @Override
    public String call() throws Exception {
        return "impllements by callable";
    }

    public static void main(String[] args) {
        ByCallable callable = new ByCallable();
        //futureTask用于接受返回值
        FutureTask<String> futureTask = new FutureTask<>(callable);
        ExecutorService es = Executors.newSingleThreadExecutor();
        es.submit(futureTask);  //不再是excute
        try {
            //futureTask.get()获取返回的值
            System.out.println(futureTask.get());
        } catch (InterruptedException e) {
            e.printStackTrace();
        } catch (ExecutionException e) {
            e.printStackTrace();
        }finally {
            es.shutdown();
        }
    }
}    

线程常用基础方法

sleep

使当前线程睡眠一定时间(运行到阻塞),让出执行机会,,所有线程都有机会(不考虑优先级),不会让出锁,会有异常产生(interruptedException)

yiled

让出执行机会即有运行到就绪(优先级》=当前线程),不会释放锁

join

在当前线程中加入一个线程(合并在一起由并行变为顺序执行

sleep和yiled是Thread类静态方法

wait
让出运行机会( 运行到阻塞),会释放获得的锁,会有 异常产生(interruptedException),


notify/notifyAll

将等待池的对象移到等锁池

以上三个方法只能用于获得锁的代码块中,并且只有同一个对象才能一起使用

线程同步

synchronized(object) 可用于代码框

synchronized  用于方法

锁是属于对象的,

静态方法加锁只影响静态方法(即静态方法的锁属于当前类)

生产者消费者

作者自己写的,若有错误请指出

商品:馒头类

public class Mantou {
    private int id;

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

    @Override
    public String toString() {
        return "Mantou{" +
                "id=" + id +
                '}';
    }
}

容器类

public class MtUitl {
    private int max = 10;
    private int mtnum=1;
    private int popn=1;
    private List<Mantou>mts = new ArrayList<>();
    public  void push(){
        synchronized (mts){
            System.out.println(Thread.currentThread().getName()+"开始生产了");
            while(mts.size()==max){
                System.out.println("数量足够不用生产");
                try {
                    mts.wait();
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }

            }
            mts.notifyAll();
            Mantou m = new Mantou(mtnum);

            mts.add(m);
            mtnum++;
            System.out.println(Thread.currentThread().getName()+"生产了"+m);
        }

    }
    public   void pop(){
        synchronized (mts){
            //放置消费超量,一直wait没有响应,多个消费者线程才会出现,单个的时候可以不用
            if(popn==21){
                return;
            }
            popn++;
            System.out.println(Thread.currentThread().getName()+"开始消费了");
            while(mts.size()==0){
                System.out.println("没有产品,请稍等。。。。");
                try {
                    mts.wait();
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }

            }
            Mantou m = mts.get(mts.size()-1);
            System.out.println(Thread.currentThread().getName()+"消费了"+m);
            mts.notifyAll();
            mts.remove(m);
        }

    }
}

生产者

public class Producer implements  Runnable{
    private static int countId=0;
    private final int id = ++countId;
    private static int mtNum= 1;
    private MtUitl mtUitl;

    public Producer(MtUitl mtUitl) {
        this.mtUitl = mtUitl;
    }

    @Override
    public void run() {
        for(;mtNum<20;mtNum++) {
            mtUitl.push();
            //System.out.println("生产者"+id+"生产了");
        }
    }
}
消费者
public class Customer implements  Runnable {
    private static int countId=0;
    private   final int id = ++countId;
    private MtUitl mtUitl;
    private static int mt = 1;

    public Customer(MtUitl mtUitl) {
        this.mtUitl = mtUitl;
    }

    @Override
    public void run() {
       for(;mt<20;mt++){
           mtUitl.pop();
           //System.out.println("消费者"+id+"消费了++++++++++++++++"+mantou);
       }
    }
}

测试类

public class Test {
    public static void main(String[] args) {
        MtUitl m = new MtUitl();
        Customer customer = new Customer(m);
        Customer customer1 = new Customer(m);
        Customer customer2 = new Customer(m);

        Thread thread1 = new Thread(customer);
        thread1.setName("消费者1》》》》》");
        Thread thread2 = new Thread(customer1);
        thread2.setName("——-----------------------------------------消费者2");
        Thread thread3 = new Thread(customer2);
        thread3.setName(">>>>>>>>>>>>>>>>>>>>>>>>>>>>>>消费者3");

        Producer p = new Producer(m);
        Producer p1 = new Producer(m);
        Thread thread4 = new Thread(p);
        thread4.setName("生产者1@@@@@@@@");

        Thread thread5 = new Thread(p1);
        thread5.setName("@@@@@@@@@@@生产者2");

      thread1.start();thread2.start();thread3.start();thread4.start(); thread5.start();
}}



  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值