您的位置:首页 > 编程语言 > Java开发

Java基础高级二(多线程)

2016-02-16 15:13 351 查看
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();

} }
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: