Java_线程

什么是进程?
  进程是指可执行程序并存放在计算机存储器的一个指令序列,它是一个动态的执行过程;
  多任务可以同时进行
什么是线程?
  线程是比进程更小的运行单位,线程相当于一个子程序;
  cpu通过时间片轮转的方式来达到多任务同时运行的效果
线程的创建:
  一 : 创建Thread类的子类
  二 : 创建实现Runnable接口的类

1、代码复杂程度:

继承Thread方式简单

实现Runnable接口的方式比较复杂

2、实现原理:

继承方式:调用start方法,调用start0方法,start0是本地方法(native),由虚拟机

实现,是C语言实现的方法,所以在java中看不到代码。本地方法start0返回来调用java中

的run方法,run方法已经在子类中重写过了,所以最终运行的是子类重写了的run方法

实现方式:构造方法中,将Runnable的实现类对象传入构造方法中,经过一路init方法的

传递,最终,用于给Thread类型中的某个成员变量(target)赋值;调用对象的start方

法,最终也是返回来调用Thread类中的run方法,判断当前的成员变量target是否为null,

如果不为null,就调用target的run方法,而这个run方法我们已经重写过了,最终运行的是

我们重写过的run方法。

3、设计:java中只支持单继承、不支持多继承

继承方式:某个类继承了Thread类,那么就无法继承其他业务中需要的类型,就限制了

我们的设计。所以扩展性较差。

实现方式:某个类通过实现Runnable的方式完成了多线程的设计,仍然可以继承当前业

务中的其他类型,扩展性较强。

4、灵活性:

继承方式:将线程对象和任务内容绑定在了一起,耦合性较强、灵活性较差

实现方式:将线程对象和任务对象分离,耦合性就降低,灵活性增强:同一个任务可以

被多个线程对象执行,某个线程对象也可以执行其他的任务对象。并且将来还可以将任务类

对象,提交到线程池中运行;任务类对象可以被不同线程运行,方便进行线程之间的数据交

有返回值的线程创建方式  实现Callable接口

1、步骤:

(1)定义一个类实现Callable接口

(2)在实现类中重写call()方法

(3)创建实现类的对象

(4)创建Future接口的实现类FutureTask对象,把实现类对象作为构造方法的参数

(5)创建Thread类的对象,把FutureTask对象作为构造方法的参数

(6)启动线程

(7)FutureTask对象再调用get方法,就可以获取线程结束之后的结果

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

public class Demo03_ImplCallable {
    /*
    * 1、Runnable没有返回值,callable有
    * 2、Runnable不能抛异常,但callable可以
    *
    * */

    public static void main(String[] args) throws ExecutionException, InterruptedException {
        //3.创建Callable接口的实现类对象
        CallImpl c = new CallImpl();

        //4.将Callable的实现类对象,包装成一个任务对象FutureTask
        FutureTask<String> task = new FutureTask<>(c);

        //5.创建线程对象,将任务对象添加到线程中
        Thread t = new Thread(task);

        //6.启动线程
        t.start();

        //7.可以使用FutureTask的get方法,获取传入的Callable对象的call方法返回的结果
        String s = task.get();
        System.out.println(s);
    }
}

//1.自定义类型,实现Callable接口
class CallImpl implements Callable<String> {

    //2.实现call方法
    @Override
    public String call() throws Exception {
        for (int i = 0; i < 10; i++) {
            System.out.println("嫁给我吧!");

            if(i == 11) {
                throw new Exception();
            }
        }

        return "滚";
    }
}


线程的状态:
  1.新建(New)
  2.可运行(Runnable)
  3.运行时(Running)
  4.阻塞(Blocked)
  5.终止(Dead)
                                                         线程的生命周期

 

线程的优先级:
  Java为线程一共了10个优先级;数字越大,优先级越高
  优先级可以用1-10的整数表示,超出范围会抛出异常;
  main()主线程的默认优先级为5;
常量优先级:MAX_PRIORITY:最高优先级10
  MIN_PRIORITY:最高优先级0
  NORM_PRIORITY:默认优先级5
  注意:线程优先级的设置受操作系统环境的影响,不能完全保证优先级高的线程就一定优先运行;

线程同步
  各个线程通过竞争CPU时间而获得运行机会;
  各线程占用CPU的时间是不可预测的;
  一个线程在什么时候会被暂停也是不可预测的;
  使用同步关键字synchronized将对象锁定,只允许一个线程对当前对象进行操作
  同步方法:public synchronized void add(){}
  同步语句块:synchronized(obj){} obj是指要锁定的对象,如 synchronized(this){}
线程间通信
  生产者和消费者问题:
  定义一个boolean变量,把当前对象看作一个容器,为true时,表示容器中有产品,不需要生产(线程等待),可以消费;为false时,需要生产,才能消费(线程等待).
  激活wait()线程的方法:notify()唤醒等待的某一个线程(随机).
  notifyAll()唤醒所有线程.

posted @ 2018-07-03 09:27  HJ0101  阅读(93)  评论(0编辑  收藏  举报