Java基础高级二(多线程)

1.进程和线程的区别:线程是轻量级的,本省不会持太多资源,需要的时候向进程申请

2.线程的状态:创建,可执行,执行中,等待,休眠,阻塞

3.线程状态之间的转换

4.线程API:Thread类,Runnable类,Object类的wait/notify方法

5.线程同步控制:同步方法,同步代码块

6.等待唤醒机制

7.线程间通信

1.进程和线程的区别

2.线程创建方式-继承Thread

线程创建的两种方式:

方式一:继承Thread类

自定义类继承Thread,并复写父类中的run(),将线程运行的方法放到run方法体重

创建类对象的同时,线程就被创建

调出线程的start方法,开启线程

方式二:实现Ruunable接口

自定义类实现Runnable接口,并覆盖接口中的run(),将线程运行的方法放到run()方法体重

创建实现Runnable接口的子类对象,把它作为参数传递给Thread类的构造函数,创建一个Thread对象

java可以多线程开发

调用线程的start方法,开启线程

两种方式的区别?

3.线程运行的特点

线程运行的随机性

 4.线程的生命周期

线程是一个执行路径,调度单元

java程序                    Thread调度

new Thread              Runnable   可运行态

start Thread             Runnning   运行态              Blocked/Waiting 阻塞、等待

                               Dead

5. 获取当前线程对象和线程名称的获取

每个线程都有默认的名称

按照面向对象思想,get方法getName()

获取线程对象Thread.currentThread()

获取线程名称demo1.getName()

 Demo demo1=new Demo("Thread-demo1");

设置线程名称demo1.setName();

6.线程创建方式二实现Runnable

// 通过Thread的构造函数,传一个实现Runnable接口的对象,四个线程同享一份资源(可以把new TicketWin()对象传进来)
  Thread win1 = new Thread(new TicketWin());
  Thread win2 = new Thread(new TicketWin());
  Thread win3 = new Thread(new TicketWin());
  Thread win4 = new Thread(new TicketWin());
  // 当前对象没有start方法,Thread类里有
  win1.start();
  win2.start();
  win3.start();
  win4.start();

 7.线程两种创建方式的区别

把不变的东西封装起来,把变的暴露出去

把run()方法抽取出来,变成共性方法,Runnable接口是方法的声明

自定义类实现Runnable接口,复写run()方法,实现该方法,但是这个类不是Tread类,没有其中的方法,这个类作为形参传给Thread类中

 实现Runnable接口,解决了extends Thread de 单继承的局限性,还可以进行数据资源共享

Thread类每一个子线程都有自己的private int num这个变量

8.线程安全问题的产生

导致安全问题出现的原因

1.1 多线程访问出现延迟

1.2 线程的随机性

通过Thread构造函数,传一个实现Runnable接口的对象,实现四个线程共享一份资源

cpu的执行权被另一个线程抢走,另一个线程执行代码体

多线程资源共享,可能发生的安全问题

1.线程随机性,线程的优先级决定

2.线程执行过程中的延迟

9.线程安全问题的解决方案

1.1同步(synchronized)

代码执行完才释放cpu执行权

10线程同步的原理

 同步的原理:锁机制,线程在执行同步代码体的时候,首先会判断同步锁,同步锁就是是否有线程正在执行

如果这个时候,已经有一个线程进来,同步锁就相当于把同步代码块锁上,阻止其他线程

11.线程同步的另一个体现-同步函数

同步其实是对一段代码的封装操作
 *  函数也是对代码的一个封装
 * 
 *  同步的另一种体现形式,同步函数
 *  同步函数的体现:public synchronized void funName(){
 *  ...
 *  }
 *  同步函数的锁:
 *  this 当前对象,函数需要被对象调用

12.同步函数使用的锁

同步函数的锁:
 *  非静态同步函数使用的是this锁
 *  静态同步函数使用的是当前类的(TicketWin2.class)的字节码
 *  this 当前对象,函数需要被对象调用

13.同步函数和同步代码块的选择

同步代码块

synchronized(锁对象){

需要同步的代码

}

同步函数

public synchronized void run(){

执行代码

}

14.线程间通信示例

 同步代码块的使用是执行同步代码块的是两个线程

多个线程间资源共享,使用同一个锁

线程创建:参数是实现Runnable接口的子类对象

线程同步代码块synchronized(同步锁){

}

15.线程间通信--等待唤醒机制

 16.线程间通信

notify() 唤醒同一个锁等待的单个线程

notifyAll()唤醒同一个对象监视器上等待的所有线程

wait() 在其他线程调用此对象的notify()方法前,导致当前线程等待,是把当前线程从运行态转变成阻塞态

17.wait()和sleep(),都让线程从运行态变为阻塞态

wait()释放cpu执行权,释放锁

sleep()释放cpu,不释放锁

sleep的线程不会占用cpu,但也不释放资源

wait() 与sleep()的区别
 * 所属类
 * 1.wait()被定义在Object类中,有函数的重载形式,可以有毫秒值,也可以没有
 *   sleep()被定义在Thread类中,并且有一个static方法,该方法必须传毫秒值
 * 2.wait()必须写在同步代码块中,必须要有锁的支持
 *   sleep()可以写在任意地方,但是具体让那个线程休眠,取决于哪个线程在执行该代码
 * 3. wait() 释放cpu执行权,其他线程还有机会抢到执行权,同时释放锁
 *   sleep() 释放了cpu的执行权,但是没有释放锁(资源)

18.停止线程的方式

Thread类中stop方法

改方法已经被标注为过时的方法

线程执行的代码结束,run()代码体结束

线程运行代码一般都是循环,定义标记控制循环结束即可

如果线程处于冻结状态,执行不到控制循环标记,可以使用Thread类的interrupt()方法

19 守护线程setDeamon

setDeamon(boolean on) 在线程开启前调用

/*
 * 守护线程
 * 线程分两种:前台线程和后台线程
 * 线程的默认创建的时候为前台线程
 * 后台线程(守护线程或用户线程)是为前台线程服务的
 * setDeamon(true):将一个线程对象设置为后台线程
 * 前台线程结束只能通过run方法体的结束,来结束线程
 * 后台线程的生命周期依赖于前台线程,前台线程一旦结束,后台线程不管代码有没有执行结束,线程都结束
 *
 */

20线程方法join()

线程对象

非静态方法

public final void join()

* 线程方法join()等待该线程结束
 * 线程对象调用
 * join()让当前线程执行结束,才允许其他线程抢夺cpu执行权

21 线程方法yield

临时暂停当前正在执行的线程对象,去执行其他线程

Thread[Thread-1线程名称,5优先级,main线程组]----9

 静态属性 MAX_PRIORITY

              MIN_PRIORITY

             norm_PRIORITY 默认

setPriority 更改线程优先级,os操作系统在进行cpu分配的时候,跟优先级有关,优先级高抢到cpu,从1到10的常量级

22集合的线程安全问题

当多个线程同时对list对象进行操作时

a线程添加元素,b线程删除元素

 遇到的问题;数据错乱

解决方法;1.自己使用同步机制控制2,把普通集合对象转换为线程安全的集合对象

a线程遍历元素,b线程添加/删除元素

  遇到问题:同步修改一样java.util.concurrentMondilicalionException

解决方法:1.自己使用同步机制控制2.把普通集合对象转换为线程安全的集合对象,并且遍历是还需要手动同步

final List list = new ArrayList();
  // 线程安全的集合
  List list2 = Collections.synchronizedList(list);
  list.add("a");

Thread athread = new Thread(new Runnable() {

   public void run() {     while (true) {      try {       Thread.sleep(10);      } catch (InterruptedException e) {       // TODO 自动生成的 catch 块       e.printStackTrace();      }      synchronized (list) {       // 遍历集合       Iterator it = list.iterator();       while (it.hasNext()) {        System.out.println(it.next() + ",");       }       System.out.println();      }

    }

   }

  }, "a");   athread.start();   // 开启第二个线程   Thread bthread = new Thread(new Runnable() {

   public void run() {     while (true) {      synchronized (list) {       list.add("k");       try {        Thread.sleep(100);       } catch (InterruptedException e) {        // TODO 自动生成的 catch 块        e.printStackTrace();       }      }

    }

   }

  }, "b");   bthread.start();

 } }

原文地址:https://www.cnblogs.com/shiyeyeyeye/p/5192807.html