《JAVA多线程》
来源:互联网 发布:程序员年纪大了怎么办 编辑:程序博客网 时间:2024/05/22 16:58
一. run()与start()的区别
1. 对象.run()是用对象调用run()方法,而对象.start()是将run()作为线程方法,进行调用。
2.
对象A.run();
对象B.run();
是执行完A所有的run()方法再执行B的run()方法。
对象A.start();
对象B.start();
是A与B的run()方法同步执行,A先执行一次再到B执行一次。
二.多线程的优点
1. 加快程序的运行速度;
2. 使用GUI界面设计,利用事件处理和GUI可以弹出进度条显示处理的进度等
3. 在一些等待的任务的实现上可以使用线程。如用户输入、文件读写和网络收发数据等,在这种情况下我们可以释放一些资源,如内存占用、CPU占用等。
三. 创建线程的方式(重点)
线程的创建方式有两种,继承Thread类和实现Runnable接口
1. 继承Thread类
//例14.3 该程序分别打印线程A、线程B、线程C各3次
public class MultiThreadExample1 {
public static void main(Stringargs[]) {
MyThread1 t1 =new MyThread1("A");// 创建线程对象t1,①
MyThread1 t2 = newMyThread1("B");
MyThread1 t3 = newMyThread1("C");
t1.start();// 启动线程t1,
t2.start();
t3.start();
}
}
class MyThread1 extends Thread {// 定义线程类MyThread1,必须继承类Thread
String name;
public MyThread1(String n) {
name = n;
}
public void run(){// 线程执行主体,②
for (int i = 0; i < 3;i++) {
try {
Thread.sleep((long)Math.random() * 1000);
} catch(InterruptedException e) {
e.printStackTrace();
}
System.out.println("访问:" + name);
}
}
}
①start()方法首先要进行必要的初始化,如设定线程运行状态,然后才能调用run()方法启动线程,所以不调用start()而直接调用run()方法是无法启动线程的。
②注意Thread类创建本身的run()是空的,子类继承必须覆盖run()方法
2.实现Runnable接口创建线程
//例14.4 该程序分别打印线程A、线程B、线程C各3次
public class MultiThreadExample2 {
public static void main(Stringargs[]) {
// 将MyThread2的对象作为Thread类的构造方法的参数,创建线程对象
Thread t1 = newThread(new MyThread2("A"));
//或者 Runnable a=new MyThread2("A");
Threadt1=new Thread(a);
Thread t2 = new Thread(newMyThread2("B"));
Thread t3 = new Thread(newMyThread2("C"));
t1.start();// 启动线程t1
t2.start();
t3.start();
}
}
class MyThread2 implements Runnable {
// 定义线程类MyThread2,实现Runnable接口
String name;
public MyThread2(String n) {
name = n;
}
public void run(){// 线程执行主体
for (int i = 0; i < 3;i++) {
try {
Thread.sleep((long)Math.random() * 1000);
} catch(InterruptedException e) {
e.printStackTrace();
}
System.out.println("访问:" + name);
}
}
}
3.两种创建线程方式的比较
(1)从继承方面,Java不支持多重继承,一个继承了Thread的类将无法再继承其他类,因此在某些情况只能采用实现Runnbale接口的方式。
(2)从调用语句方面,Thread可以直接调用当前线程自身的方法,而实现Runnable接口的方法需要形如Runnable a=new MyThread2("A");Thread t1=new Thread(a);较麻烦。
(3)如要获取拥有特殊功能的线程必须通过继承并扩充Thread接口实现或对Thread类的修改或扩充不大,更应采用继承Thread类的方式。
4.多线程的生命周期
常用的Thread对象方法:
String getNmae()//获取线程名
static Thread currentThread()//返回当前线程
void destroy()//销毁线程
5.线程间的协作
synchronized()方法:用其控制对类成员变量的访问,每个设置了synchronized 的方法一旦被执行,就独占该锁,知道该方法返回才将锁释放,才轮到下一个线程执行。
典型举例(生产者与消费者的问题):
//实例14.7 Box对象用来存放数据
public class Box {
privateint value;
//是否可以使用,true可读取数据,false可写入数据
privateboolean available = false;
publicvoid put(int value) {
while(available == true) {
try{
wait();//等待,提供给其他线程使用
}catch(InterruptedException e) {
e.printStackTrace();
}
}
available= true;// 表示可读取数据
notifyAll();//唤醒所有等待线程
this.value= value;// 写入数据
}
publicint get() {
while(available == false) {
try{
wait();
}catch (InterruptedException e) {
e.printStackTrace();
}
}
available= false;// 表示可写入数据
notifyAll();//唤醒所有等待线程
returnthis.value;// 读取数据
}
}
public class 生产者 extends Thread {//生产者对象产生数据
privateBox box;
privateString name;
public生产者(Box b, String n) {
box= b;
name= n;
}
publicvoid run() {
for(int i = 1; i < 6; i++) {
synchronized (box) {//Java线程通过锁定一个对象来达到分别对box对象进行操作的目的
box.put(i);//存放数据i入box对象
System.out.println("生产者" + name + "生产产品:" + i);
try{
sleep((int)(Math.random() * 100));
}catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
}
public class 消费者 extends Thread {//消费者对象获取数据
privateBox box;
privateString name;
public消费者(Box b, String n) {
box= b;
name= n;
}
publicvoid run() {
for(int i = 1; i < 6; i++) {
synchronized (box){
box.get();//从box对象中取出数据i
System.out.println("消费者" + name + "取得产品:" + i);
try{
sleep((int)(Math.random() * 100));
}catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
}
public class 生产者消费者测试 {//主类
publicstatic void main(String args[]) {
Boxbox = new Box();
生产者 p = new 生产者(box, "001");// 创建生产者001,往box对象中存数据
消费者 c = new 消费者(box, "002");// 创建消费者002,从box对象中取数据
p.start();
c.start();
}
}
注意:若不注意使用协作,会出现两个对象分别不按先后执行相关方法,导致处于资源竞争的状态。
- 【Java多线程】多线程死锁
- Java 多线程
- java 多线程
- java多线程
- JAVA多线程
- java多线程
- JAVA多线程
- java多线程
- JAVA 多线程
- Java多线程
- java多线程
- JAVA 多线程
- Java 多线程
- Java 多线程
- java多线程
- Java 多线程
- Java多线程
- java 多线程
- POJ 1991 DP
- 普利姆算法
- java内部类
- 最近老是忘了冒泡的方法,555,老师让我们“减”起来!
- 升级IE6提示“以前的安装有尚未完成的操作,需重新启动”
- 《JAVA多线程》
- Dreamweaver CSs网页设计css规则定义翻译
- codevs 2598 编辑距离问题
- usaco Mixing Milk
- C语言--函数指针与函数指针数组
- 利用函数封装完成数组方阵的转置
- 【Android】11、相对布局RelativeLayout常用属性
- Android中如何在子线程执行任务完成后更新UI
- 【十三】高斯混合模型