黑马程序员_多线程

来源:互联网 发布:mac能玩iphone手游 编辑:程序博客网 时间:2024/06/05 07:06

------- android培训、java培训、期待与您交流! ----------

/*|-java.lang |-Thread|-currentThread() 获取当前线程|-join() 加入某线程,待此线程执行完。再执行其他线程。|-yield() 暂停当前正在执行的线程对象,并执行其他线程。|-sleep(long millis) |-start() 启动线程并调用run()|-getName() |-interrupt() 中断线程|-setDaemon(true) 设置为守护线程|-setName(name) |-setPriority(NORM_PRIORITY) */

Thread implements Runnable


***************

1).进程与线程:

进程:一个正在执行中的程序。

线程:进程中的一个独立的控制单元。

关系:线程在控制着进程的执行。


1.每个线程都有一个优先级,高优先级线程的执行优先于低优先级线程。

2.每个线程都可以或不可以标记为一个守护程序。

3.当某个线程中运行的代码创建一个新 Thread 对象时,

该新线程的初始优先级被设定为创建线程的优先级,并且当且仅当创建线程是守护线程时,

新线程才是守护程序。 


***************

2).创建线程:

1.继承Thread类,重写run方法

  步骤:

1.类A继承Trhead类

2.重写run方法。

3.调用线程的start方法启动线程,调用run方法

class A extends Thread {public void run() {System.out.println("run!");}}----------------new A().start();

2.声明实现Runnable接口,重写run方法。

  步骤:

1.类A实现Runnable接口

2.重写Runnable接口中的run方法

3.通过Thread类建立线程对象 

4.将Runnable接口的子类A的对象传递给Thread类的构造函数

5.调用Thread类的start方法开启线程并调用Runnable接口子类的run方法

class Ticket implements Runnable {private int tick = 100;// 共有100张票public void run() {//重写Runnable接口run方法while(true){// 如果还有票if(tick > 0)System.out.println(Thread.currentThread().getName()+" : "+tick--);// 打印当前线程名称}}}----------------Ticket t = new Ticket();new Thread(t).start();

***************

3).实现方式和继承方式有什么区别?

实现方式:线程代码存放在Runnable接口的子类的run方法

继承方式:线程代码存放在Thread类run方法中


继承了Thread类就不能继承其它类了

实现方式好处:避免了单继承的局限性


***************

4).线程的5种状态:

1.被创建状态:创建好。未启动的线程的状态。

2.运行状态:获取到cpu执行权,正在运行状态。

3.阻塞状态:具备运行资格,但没有获取到cpu执行权。

4.冻结状态:线程wait()或sleep()了,需等待另一个线程notify()或sleep时间到;

5.终止状态:已终止线程的线程状态。线程已经结束执行。 

只有run运行完,才能结束。以前的版本有stop()方法终止线程。因为会出现bug就停用了。


***************

5).多线程用到同步:synchronized(obj)

1.解决了多线程访问会出现的安全问题:

1.使用同步 synchronized(obj),执行一个线程时,其它的线程用wait()等待。

2.对象如同锁。持有锁的线程可以在同步中执行。

3.没有持有锁的线程即使获取cpu的执行权,也进不去,因为没有获取锁。

2.同步的前提:

1.必须有2个及以上的线程。

2.多个线程必须使用同一个锁。

3.同步的利与弊:

好处:解决了多线程的安全问题。

弊端:多个线程需要判断锁,较为消耗资源,

4.同步的方式及所有的锁:

1.同步代码块:使用的锁是任意对象

synchronized(obj){需要同步的代码}

2.同步非静态函数:使用的锁是this

public synchronized void method(){}

3.同步静态函数:使用的锁是该方法所属类的字节码对象,类名.class

public static synchronized void method(){}

静态进内存,内存中没有本类对象


***************

6).如何找一个程序会出现的安全问题?

1,明确多线程要运行的代码。

2,明确共享数据。

3,明确多线程要运行的代码中的操作共享数据的语句。


***************

7).单例设计模式:

饿汉式:

class Single {private static Single s = new Single();private Single(){}public static void getInstance() {return s;}}
懒汉式:
class Single {private static Single s = null;private Single(){}public static void getInstance() {if(s==null) {//多线程访问会出现安全问题,所以用到同步。synchronized(Single.class) {if(s==null)s = new Single();}return s;}}

***************

8).死锁:同步中嵌套同步

class Ticket implements Runnable{private  int tick = 1000;Object obj = new Object();boolean flag = true;public  void run(){//覆写run方法if(flag){while(true){synchronized(obj){show();}}}elsewhile(true)show();}public synchronized void show(){synchronized(obj){if(tick>0) {try{Thread.sleep(10);}catch(Exception e){}System.out.println(Thread.currentThread().getName()+"----"+ tick--);}}}}class  DeadLockDemo{public static void main(String[] args) {Ticket t = new Ticket();Thread t1 = new Thread(t);//创建线程对象接收Runnable子类引用Thread t2 = new Thread(t);t1.start();try{Thread.sleep(10);}catch(Exception e){}t.flag = false;t2.start();}}


***************

线程间通信:多个线程操作同一个资源。操作动作不同。

例:生产一个商品,然后将这个商品消费掉。然后再生产再消费。


***************

等待唤醒机制:

wait(),notify(),notifyAll()这些方法都用在同步中操作持有锁的线程。


1.只有同步中有锁,所以这些方法只能用在同步中。

2.这些方法操作线程时。需标识所操作的锁。

3.只有操作相同锁的notify()能唤醒相同锁的wait()。

4.锁可以是任意对象,被任意对象调用的这些方法定义在Object中。


***************

停止线程:

1.只有run方法结束。

多线程运行的代码通常是循环结构。

只要控制住循环,就可以让run方法结束,也就是线程结束。

2.特殊情况:线程在调用wait(),jion()或sleep()的过程中受阻。

使用interrupt()可清除其中断状态,并收到一个 InterruptedException

catch语句捕获到此异常。所以可以在catch语句中改变操作标记让线程结束。

即:

boolean flag = true;while(flag) {...catch(Exception e){...flag = false;}...}

***************

优先级:1-10级

NORM_PRIORITY 默认等级5

MAX_PRIORITY 最高等级10

MIN_PRIORITY 最低等级1

设置优先级用于让线程有优先执行权,即抢夺执行权的概率大些。


***************

守护线程:setDaemon

2.线程启动前调用。

3.只剩下的线程都是守护线程,Java虚拟机退出。

象棋中将帅之外的棋可理解为是守护线程。


***************

Join():让某个线程得到cpu执行权,执行完再执行别的线程。

可用于临时加入某个要操作的线程。


***************

yield():让某个线程等其它线程执行完在执行。

可用于暂停当前这个不重要的线程。 



 
0 0
原创粉丝点击