程序,过程,线程

  • 程序:为实现特定工作,应用某种语言编写的一组指令的汇合,是一段动态的代码。
  • 过程:程序的一次运行过程,或者是正在运行的一个程序。过程是资源分配的根本单位。
  • 线程:线程由过程进一步细化而来,是一个程序外部的一条执行门路。线程是调度和执行的单位,每个线程领有独立的运行栈和程序计数器,线程开销很小。

Thread生命周期

Thread类中的罕用办法

  • start():启动以后线程;调用以后线程的run()。
  • run():通常须要重写Thread类中的此办法,将创立的线程要执行的操作申明在此办法中。
  • currentThread():静态方法,返回执行以后代码的线程。
  • getName():获取以后线程的名字。
  • setName():设置以后线程的名字。
  • yield():开释以后cpu的执行权。
  • join():在线程a中调用线程b的join()办法,此时线程a就进入阻塞状态,直到线程b齐全执行完当前,线程a才完结阻塞状态。
  • sleep(long millitime):让以后线程“睡眠”指定的millitime毫秒。在指定的millitime毫秒工夫内,以后线程是阻塞状态。
  • isAlive():判断以后线程是否存活。
  • getPriority():获取线程的优先级。
  • setPriority(int p):设置线程的优先级。
  • 线程的优先级有以下三种,MAX_PRIORITY:10;MIN _PRIORITY:1;NORM_PRIORITY:5。

创立多线程的形式

继承Thread类

步骤:

  • 创立一个继承于Thread类的子类;
  • 重写Thread类中的run()办法,将次线程执行的操作申明在run()办法中。
  • 创立Thread类的子类对象。
  • 通过此对象调用start()。

举例:三个窗口进行卖票(存在线程平安问题)

class MThread extends Thread{    private static int tickets = 100;    @Override    public void run() {        while(true){            if(tickets > 0){                System.out.println(getName() + "卖票,票号为:" + tickets--);            }else{                break;            }        }    }}public class ThreadTest {    public static void main(String[] args) {        MThread t1 = new MThread ();        MThread t2 = new MThread ();        MThread t3 = new MThread ();        t1.setName("窗口1");        t2.setName("窗口2");        t3.setName("窗口3");        t1.start();        t2.start();        t3.start();    }}

阐明:局限于类的单继承性。

实现Runnable接口

步骤:

  • 创立一个实现Runnable接口的类。
  • 实现类去实现Runnable中的形象办法:run()。
  • 创立实现类的对象。
  • 将此对象作为参数传递到Thread类的结构器中,创立Thread类的对象。
  • 通过Thread类的对象调用start()。

举例:三个窗口进行卖票(存在线程平安问题)

class MThread implements Runnable{   private int tickets = 100;   @Override   public void run() {       while(true){           if(tickets > 0){               System.out.println(Thread.currentThread().getName() + "卖票,票号为:" + tickets--);           }else{               break;           }       }   }}public class ThreadTest {   public static void main(String[] args) {       MThread m = new MThread();       Thread t1 = new Thread(m);       Thread t2 = new Thread(m);       Thread t3 = new Thread(m);       t1.setName("窗口1");       t2.setName("窗口2");       t3.setName("窗口3");       t1.start();       t2.start();       t3.start();   }}

阐明:不会局限于类的单继承性;适宜解决多个线程共享数据的状况。

实现Callable接口

步骤:

  • 创立一个实现Callable的实现类。
  • 实现call办法,将此线程须要执行的操作申明在call()中。
  • 创立Callable接口实现类的对象。
  • 将此Callable接口实现类的对象作为参数传递到FutureTask结构器中,创立FutureTask的对象。
  • 将FutureTask的对象作为参数传递到Thread类的结构器中,创立Thread对象,并调用start()。

举例:遍历100以内的偶数,并且计算他们的和

class MThread implements Callable{    @Override    public Object call() throws Exception {        int sum = 0;        for (int i = 2; i < 101; i+=2) {                System.out.println(i);                sum += i;            }        }        return sum;    }}public class ThreadTest {    public static void main(String[] args) {        MThread thread = new MThread ();        FutureTask futureTask = new FutureTask(thread);        new Thread(futureTask).start();        try {             //get()返回值即为FutureTask结构器参数Callable实现类重写的call()的返回值。            Object sum = futureTask.get();            System.out.println("总和为:" + sum);        } catch (InterruptedException e) {            e.printStackTrace();        } catch (ExecutionException e) {            e.printStackTrace();        }    }}

阐明:call()办法有返回值,并且能够抛出异样;callable反对泛型。

线程池

步骤:

  • 提供指定线程数量的线程池。
  • 执行指定的线程的操作。须要提供实现Runnable接口或Callable接口实现类的对象。
  • 敞开线程池。

举例:两个线程遍历100以内的奇偶数

class NumberThread implements Runnable{    @Override    public void run() {        for(int i = 1;i < 101; i+=2){             System.out.println(Thread.currentThread().getName() + ": " + i);        }    }}class NumberThread1 implements Runnable{    @Override    public void run() {        for(int i = 2;i < 101; i+=2){            System.out.println(Thread.currentThread().getName() + ": " + i);        }    }}public class ThreadPool {    public static void main(String[] args) {         ExecutorService service = Executors.newFixedThreadPool(10);        ThreadPoolExecutor service1 = (ThreadPoolExecutor) service;        service.execute(new NumberThread());//实用于Runnable        service.execute(new NumberThread1());//实用于Runnable        //service.submit(Callable callable);//应用于Callable        service.shutdown();    }}

阐明:进步了响应速度;升高资源耗费;便于线程治理。

线程同步机制

解决线程平安问题

同步代码块

synchronized(对象){//须要被同步的代码}
举例:三个窗口卖票

class Windows extends Thread{    private static int tickets = 100;    @Override    public void run() {        while(true){            synchronized(Windows.class){                try {                    Thread.sleep(10);                } catch (InterruptedException e) {                    e.printStackTrace();                }                if(tickets > 0){                    System.out.println(getName() + "卖票,票号为:" + tickets--);                }else{                    break;                }            }        }    }}public class Test {    public static void main(String[] args) {        Windows t1 = new Windows();        Windows t2 = new Windows();        Windows t3 = new Windows();        t1.setName("窗口1");        t2.setName("窗口2");        t3.setName("窗口3");        t1.start();        t2.start();        t3.start();    }}

同步办法

将synchronized放到办法的申明中。
举例:三个窗口卖票。

class Windows implements Runnable {    private int tickets = 100;    @Override    public void run() {        while(true){            show();        }    }    private synchronized void show(){        if(tickets > 0){            try {                Thread.sleep(10);            } catch (InterruptedException e) {                e.printStackTrace();            }            System.out.println(Thread.currentThread().getName() + "卖票,票号为:" + tickets--);        }    }}public class Test{    public static void main(String[] args) {        Windows t = new Windows();        Thread t1 = new Thread(t);        Thread t2 = new Thread(t);        Thread t3 = new Thread(t);        t1.setName("窗口1");        t2.setName("窗口2");        t3.setName("窗口3");        t1.start();t2.start();t3.start();    }}

Lock

class A{    private final ReentrantLock lock = new ReentrantLock();    public void m(){        lock.lock();        try{            //保障线程平安的代码        }        finally{            lock.unlock();        }    }}

举例:三个窗口卖票

class Window implements Runnable{    private int ticket = 100;    private ReentrantLock lock = new ReentrantLock();    @Override    public void run() {        while(true){            try{                lock.lock();                if(ticket > 0){                    try {                        Thread.sleep(10);                    } catch (InterruptedException e) {                        e.printStackTrace();                    }                    System.out.println(Thread.currentThread().getName() + "卖票,票号为:" + ticket--);                }            }finally {                lock.unlock();            }        }    }}public class LockTest {    public static void main(String[] args) {        Window w = new Window();        Thread t1 = new Thread(w);        Thread t2 = new Thread(w);        Thread t3 = new Thread(w);        t1.setName("线程1");t2.setName("线程2");t3.setName("线程3");        t1.start();t2.start();t3.start();    }}

synchronized和lock比照:

  • lock是显示锁,手动开启和敞开;synchronized是隐式锁,出了作用域主动开释。
  • lock只有代码块锁;synchronized有代码块锁和办法锁。
  • 应用lock锁,JVM将破费较少的工夫来调度线程,性能更好;并且具备更好的扩展性。

线程通信

三个办法

  • wait():一旦执行此办法,以后线程就进入阻塞状态,并开释同步监视器。
  • )notify():一旦执行此办法,就会唤醒被wait的一个线程。如果有多个线程被wait,就唤醒优先级高的那个。
  • notifyAll():一旦执行此办法,就会唤醒所有被wait的线程。

阐明

  • wait(),notify(),notifyAll()三个办法必须应用在同步代码块或同步办法中。
  • wait(),notify(),notifyAll()三个办法的调用者必须是同步代码块或同步办法中的同步监视器。否则,会呈现IllegalMonitorStateException异样。
  • wait(),notify(),notifyAll()三个办法是定义在java.lang.Object类中。

举例:生产者消费者问题

class Clerk{    private int productCount = 0;    public synchronized void produceProduct(){        if(productCount < 20){            productCount ++;            System.out.println(Thread.currentThread().getName() + "生产第" + productCount + "个产品");            notify();        }else {            try {                wait();            } catch (InterruptedException e) {                e.printStackTrace();            }        }    }    public synchronized void consumeProduct() {        if(productCount > 0){            System.out.println(Thread.currentThread().getName() + "生产第" + productCount + "个产品");            productCount --;            notify();        }else {            try {                wait();            } catch (InterruptedException e) {                e.printStackTrace();            }        }    }}class Productor extends Thread{    private Clerk clerk;    public Productor(Clerk clerk) {        this.clerk = clerk;    }    @Override    public void run() {        System.out.println("生产者" + Thread.currentThread().getName() + "开始生产");        while(true){            try {                Thread.sleep(10);            } catch (InterruptedException e) {                e.printStackTrace();            }            clerk.produceProduct();        }    }}class Consumer extends Thread{    private Clerk clerk;    public Consumer(Clerk clerk) {        this.clerk = clerk;    }    @Override    public void run() {        System.out.println("消费者" + Thread.currentThread().getName() + "取走产品");        while(true){            try {                Thread.sleep(10);            } catch (InterruptedException e) {                e.printStackTrace();            }            clerk.consumeProduct();        }    }}public class ProductTest {    public static void main(String[] args) {        Clerk clerk = new Clerk();        Productor p1 = new Productor(clerk);        p1.setName("生产者1");        Consumer c1 = new Consumer(clerk);        c1.setName("消费者1");        p1.start();c1.start();    }}

最初

在文章的最初作者为大家整顿了很多材料!包含java外围知识点+全套架构师学习材料和视频+一线大厂面试宝典+面试简历模板+阿里美团网易腾讯小米爱奇艺快手哔哩哔哩面试题+Spring源码合集+Java架构实战电子书等等!

全副收费分享给大家,欢送关注公众号:前程有光支付!