黑马程序员_多线程1
来源:互联网 发布:同花顺自动交易软件 编辑:程序博客网 时间:2024/05/23 12:52
------- android培训、java培训、期待与您交流! ----------
线程:是程序中的执行线程。
Java 虚拟机允许应用程序并发地运行多个执行线程。
一、线程的创建
创建新执行线程有两种方法。
一种方法是将类声明为 Thread 的子类。该子类应重写 Thread 类的 run 方法。接下来可以分配并启动该子类的实例。
例如,计算大于某一规定值的质数的线程可以写成:
class PrimeThread extends Thread {long minPrime;PrimeThread(long minPrime) {this.minPrime = minPrime;} public void run() {// compute primes larger than minPrime . . .}}
然后,下列代码会创建并启动一个线程:
PrimeThread p = new PrimeThread(143);p.start();
创建线程的另一种方法是声明实现 Runnable
接口的类。该类然后实现 run
方法。然后可以分配该类的实例,在创建Thread
时作为一个参数来传递并启动。
采用这种风格的同一个例子如下所示:
class PrimeRun implements Runnable {long minPrime;PrimeRun(long minPrime) {this.minPrime = minPrime;} public void run() {// compute primes larger than minPrime . . .}}
然后,下列代码会创建并启动一个线程:
PrimeRun p = new PrimeRun(143);new Thread(p).start();
那么,线程的创建方式选择哪个更好呢?
答案是实现Runnable接口更好一些。
1.因为实现Runnable接口可以避免Java单继承的局限性。
当一个类继承了Thread,就不可以在继承其他类了。
而当一个类实现了Runnable,它一样可以继承其他类。
比如 class Demo extends SuperDemo implements Runnable{}
2.更符合面向对象的设计。
run()方法的作用是用来封装线程要运行的代码。
那么run()方法所属的对象,就是线程任务对象。
Thread类的子类对象即使线程对象,又是线程任务对象。耦合性很强。
有了Runnable接口,可以将线程任务和线程进行解耦,提高了程序的扩展性。
所以建议使用Runnable接口的方式完成线程的创建。
二、多线程的安全问题
多线程安全问题:当多条语句在操作同一个线程共享数据时,一个线程对多条语句只执行了一部分,另一个线程参与进来执行,就会导致共享数据的错误。
解决办法:对多条操作共享数据的语句,只能让一个线程执行。在执行过程中,其他线程不可以参与执行。
Java提供了一种解决方式:同步代码块 synthronized(Object obj) { 需要被被同步的代码 }
Object 如同锁,持有锁的线程可以在同步代码块中执行。没有持有锁的线程即使持有CPU的执行权,也无法执行同步代码。
同步的前提:
1.必须要有两个或以上的线程
2.必须是多个线程使用同一个锁
好处:解决了多线程的安全问题。 弊端:线程需要判断锁,较为消耗资源。
如何找安全问题?
1.明确哪些代码是多线程运行代码
2.明确共享数据
3.明确多线程运行代码中哪些语句是操作共享数据的
第二种同步的方式:同步函数 用synchronized修饰函数
在非静态同步函数中,用的锁是this。因为函数需要被对象调用,那么函数都有一个所属对象引用,这个引用就是this。
在静态同步函数中,用的锁是类名.class。静态函数进内存时,内存中没有本类对象,但是一定有该类对应的字节码文件对象:类名.class,该对象的类型是Class类。
另外,在单例设计模式中有饿汉式和懒汉式,实际开发用饿汉式,但面试常考懒汉式。
懒汉式特点:实例的延迟加载
问题:多线程访问时会出现安全问题。
用同步代码块或同步函数均可,但有些低效,用双重判断解决效率问题,同步代码块使用的锁为该类所属的字节码文件对象。
class Single {private static Single s = null;private Single(){}public static Single getInstance() {if(s == null) {synchronized(Single.class) {if(s == null)s = new Single();}}return s;}}
三、死锁
通常死锁的出现是因为:同步中嵌套同步,锁却不同。
开发中要避免写出死锁程序。
下面是一个出现死锁的程序:
class DeadLock implements Runnable {private boolean flag;DeadLock(boolean flag) {this.flag = flag;}public void run() {for (int i = 0; i < 40; i++) {if(flag) {synchronized(Lock.lock1) {System.out.println("iflock1..."+i);synchronized(Lock.lock2) {System.out.println("iflock2..."+i);}}}else {synchronized(Lock.lock2) {System.out.println("elselock2..."+i);synchronized(Lock.lock1) {System.out.println("elselock1..."+i);}}}}}}class Lock {public static Object lock1 = new Object(); public static Object lock2 = new Object(); }
- 黑马程序员_多线程1
- 黑马程序员_多线程1
- 黑马程序员_多线程1
- 黑马程序员_多线程1
- 黑马程序员_多线程1
- 黑马程序员_多线程1
- 黑马程序员_多线程
- 黑马程序员_多线程
- 黑马程序员_多线程
- 黑马程序员_多线程
- 黑马程序员_多线程
- 黑马程序员_多线程
- 黑马程序员_多线程
- 黑马程序员_多线程
- 黑马程序员_多线程
- 黑马程序员_多线程
- 黑马程序员_多线程
- 黑马程序员_多线程
- ZooKeeper Distributed模式
- GNU make工具本质
- 基于visual Studio2013解决C语言竞赛题之0502最小数替换
- 打造产品经理喜欢的程序员
- 软件测试工程师
- 黑马程序员_多线程1
- HTTP报文详解
- android:DDMS查看Threads
- 重叠的 CCMenu touch 优先级问题
- 云计算服务提供商的服务模式分类小结
- Android的NDK开发
- 黑马程序员 学习笔记五:JDK5之可变参数,代替某些重载的情况
- webservice配置和发布,axis2配置
- jquery控制table中的input样式,巧妙利用标签元素,隐藏input边框