黑马程序员——多线程

来源:互联网 发布:多益网络有年终奖吗 编辑:程序博客网 时间:2024/06/05 14:42
------Java培训、Android培训、iOS培训、.Net培训、期待与您交流! -------

JVM启动的不止一个线程,还有负责垃圾回收机制的线程。

创建新执行的线程有两种方法:一、将类声明为Thread的子类;二、实现Runnable接口。

两种方法的区别在于第一种是纯粹将类作为线程类来使用,而第二种方法,类还可以作为其他类的子类,可以是一个其他类。

继承Thread类创建一个线程的步骤:

1、将类定义为Thread的子类

2、复写run()方法

3、调用start()方法启动线程,线程启动就调用run()方法

注意:将要运行的代码写在run()方法中,在调用过程中用的是start()方法而不是run()方法,区别:start()是指创建另一个线程,而调用run()则是主函数调用方法而已,单线程了。

上图重点分析,主要是理解什么是阻塞态,即具备运行资格,但没运行权。(说白了就是告诉CPU,此线程可以执行了,等待CPU处理)。冻结状态则是放弃了运行资格。

每个线程都有自己的名称,即:Thread-编号。(Thread.currentThread().getName();)

知识回顾:子类继承父类的有参构造函数时:

<span style="font-size:14px;">Zi(String name){super(name);}</span>
一个类是线程类,里面定义一个静态变量,则无论实例化多少个实例都至共享一个变量。


实现Runnable接口创建一个线程的步骤:

1、将类实现Runnable接口R

2、复写run()方法

3、通过Thread类建立线程对象,并将R的实例作为参数传给Thread的构造函数

4、Thread类对象.start();

即:new Thread(R).start();


线程的同步与通信:

JDK1.5以前的老版本:synchronized(a) wait(); notify(); notifyAll(); (其中,a为对象或是Class对象)(静态同步函数就是用Class对象)

JDK1.5以后的版本:lock(); unlock();      await();signal();signalAll();

注意:wait()和await()不仅仅将线程处于冻结状态,而且还释放当前的锁。

上面的方法是一一替代的,1.5后的优势在于:

1、同步锁时避免代码在冻结状态抛出异常而导致锁没释放 (unlock()放在finally代码块中)

2、唤醒方式可以一一对应,即a.signal()能唤醒a.await();避免了全部唤醒程序存在的bug又优化了程序资源


同步解决了多线程的安全问题,但却消耗了资源。在集合中的HashMap是线程不安全的,HashTable是线程安全的。


停止线程的唯一方法:run方法结束(运行代码一般都是有循环的,控制循环)

特殊情况:当线程处于冻结状态时,读取不到结束标识,关闭不了线程。

中断线程:当没有指定的方式让冻结的线程恢复到运行状态,inerrupted()将处于冻结状态的线程恢复到运行状态并抛InterruptedException()

a.setDaemon()可将线程a设置为守护线程,即后台线程。所有前台进程结束后剩下的都是守护线程则自动关闭。必须在a启动前使用。


线程优先级:a.join();主线程执行到这句话时候,自己挂起等a先执行完后才继续执行,如有其它线程,则与a并发,主线程等!


Thread.yield():中断当前进程,运行其它进程。


线程有优先级,1-10,一般的,1,5,10为常量,在Thread类字段中,用static final修饰。


延迟加载的单例设计模式其实就是懒汉式。

0 0