黑马程序员_java多线程技术

来源:互联网 发布:淘宝性价比高的女装店 编辑:程序博客网 时间:2024/05/18 15:55
黑马程序员_java多线程技术
------android培训、java培训、期待与您交流!------

以前一直没有写博文的习惯,感觉浪费时间,但为了进入黑马,我尝试的开始写博文,写着写着,我发现原来这种感觉还错哦。所以废话不多说,对java多线做一些总结。
一:多线程的介绍
线程是程序运行的基本执行单元。当操作系统(不包括单线程的操作系统如微软早期的DOS)在执行一个程序时会在系统中建立一个进程而在这个进程中必须至少建立一个线程这个线程被称为主线程来作为这个程序运行的入口点。因此在操作系统中运行的任何程序都至少有一个主线程。不过我们常常有这样的需求,一个应用能够同时处理多个任务,这样在某些方面将大大的提高效率。而多线程技术就可以做到这些。我们来看看,在java中如果使用多线程。

二:如何实现多线程
在java中想要实现多线程有两种手段,1.继承Thread类 2.实现Runnabl接口。
案例一(通过继承Thread类来实现多线程)
class ThreadDemo extends Thread{public void run(){//线程所要执行的代码必须放到run方法中,因为启动线程后,此线程会默认执行run方法的内容System.out.println("我是线程:"+getName());}}public class Test{public static void main(String[] args){ThreadDemo td1=new ThreadDemo();//创建线程对象ThreadDemo td2=new ThreadDemo();td1.start();//启动一个线程td2.start();}}

如果要实现多线程,并不推荐使用上面的这种方式,因为java不支持多继承,现在为了实现多线程而继承了Thread类
如果此类还想继承别的类来实现一些功能,显然就将变得不可能,上面的方式不利于程序的扩展。
于是就有了第二种java实现多线程的方式。

案例二(通过实现Runnable接口来实现多线程)
Runnable 接口只有一个方法 run(),我们声明自己的类实现 Runnable 接口并实现这一方法,将我们的线程代码写入其中,就完成了这一部分的任务。但是 Runnable 接口并没有任何对线程的支持,我们还必须创建 Thread 类的实例
class ThreadDemo implements Runnable{public void run(){System.out.println("我是线程:");}}public class Test{public static void main(String[] args){Thread td1=new Thread(new ThreadDemo());Thread td2=new Thread(new ThreadDemo());td1.start();td2.start();}}

三:多线程的四种状态
1.是创建状态。在生成线程对象,并没有调用该对象的start方法,这是线程处于创建状态。 
2.就绪状态。当调用了线程对象的start方法之后,该线程就进入了就绪状态,但是此时线程调度程序还没有把该线程设置为当前线程,此时处于就绪状态。在线程运行之后,从等待或者睡眠中回来之后,也会处于就绪状态。 
3.运行状态。线程调度程序将处于就绪状态的线程设置为当前线程,此时线程就进入了运行状态,开始运行run函数当中的代码。 
4.阻塞状态。线程正在运行的时候,被暂停,通常是为了等待某个时间的发生(比如说某项资源就绪)之后再继续运行。sleep,suspend,wait等方法都可以导致线程阻塞。 

5.死亡状态:正常情况下run() 返回使得线程死亡。调用 stop()或 destroy() 亦有同样效果,但是不被推荐,前者会产生异常,后者是强制终止,不会释放。


四:线程的同步

由于同一进程的多个线程共享同一片存储空间,在带来方便的同时,也带来了访问冲突这个严重的问题。Java语言提供了专门机制以解决这种冲突,有效避免了同一个数据对象被多个线程同时访问。我们只需针对方法提出一套机制,这套机制就是 synchronized 关键字,它包括两种用法:synchronized 方法和 synchronized 块。

1. synchronized 方法:通过在方法声明中加入synchronized关键字来声明 synchronized 方法。synchronized 方法控制对类成员变量的访问:每个类实例对应一把锁,每个 synchronized 方法都必须获得调用该方法的类实例的锁方能执行,否则所属线程阻塞,方法一旦执行,就独占该锁,直到从该方法返回时才将锁释放,此后被阻塞的线程能获得该锁,重新进入可执行状态。其所有声明为 synchronized 的成员函数中至多只有一个处于可执行状态(因为至多只有一个能够获得该类实例对应的锁),从而有效避免了类成员变量的访问冲突(只要所有可能访问类成员变量的方法均被声明为 synchronized。

如:

class ThreadDemo implements Runnable{String name;public synchronized void run(){name="你好世界";System.out.println(name);}}public class Test{public static void main(String[] args){Thread td1=new Thread(new ThreadDemo());Thread td2=new Thread(new ThreadDemo());td1.start();td2.start();}}


2. 在 Java 中,不光是类实例,每一个类也对应一把锁,我们也可将类的静态成员函数声明声明为 synchronized,以控制其对类的静态成员变量的访问。synchronized 方法的缺陷:若将一个大的方法声明为synchronized 将会大大影响效率,典型地,若将线程类的方法run()声明为synchronized ,由于在线程的整个生命期内它一直在运行,因此将导致它对本类任何synchronized方法的调用都永远不会成功。所就有了 synchronized 块的出现,通过 synchronized关键字来声明synchronized 块。

如:

class ThreadDemo implements Runnable{String name;private Object obj=new Object();//创建一个对象,用它来当锁public void run(){synchronized(obj){name="你好黑马";System.out.println(name);}}}public class Test{public static void main(String[] args){Thread td1=new Thread(new ThreadDemo());Thread td2=new Thread(new ThreadDemo());td1.start();td2.start();}}

原创粉丝点击