黑马程序员-多线程

1.定义:一个进程在执行的过程中的多条线索。

2.线程的状态与生命周期

Java语言使用thread及其子类来表示线程,新建的线程包括以下4种状态。

新建、运行、中断、死亡。

例子:

Demo9.java

public class Demo9 {
public static void main(String[] args) {//主线程
SpeakHello speakHello;
speakHello=new SpeakHello();
speakHello.start();
for (int i = 0; i < 15; i++) {
System.out.println("大家好"+i+"");
}
 }
}

SpeakHello.java

public class SpeakHello extends Thread {
public void run(){
for (int i = 0; i < 20; i++) {
System.out.println("hello"+i+"");
}
}
}

3.使用Runnable接口

直接使用thread来创建进程对象,构造方法为:Thread(Runnabele targer),该构造方法的参数是一个Runnable类型的接口,因此在创建线程是必须向构造方法的参数传递一个实现Runnable的接口类实例,该实例称作所创线程的目标对象。

例如:

Bank bank=new Bank();

bank.setMony(300);

Thread thread;

thread=new Thread(bank);

4.Run方法中的局部变量

对于具有相同目标的对象的线程,当其中一个线程享用CPU资源是,目标对象自动调用接口中的Run方法,这时,run方法的局部变量被分配内存空间,当另一个享用cpu资源时,目标对象再次调用Run方法,局部变量再次分配内存空间。不同线程的局部变量不会被干扰。例如:

Demo9.java

public class Demo9 {
public static void main(String[] args) {//主线程
Move move=new Move();
Thread zhangsan,lisi;
zhangsan=new Thread(move);
zhangsan.setName("张三");
lisi=new Thread(move);
lisi.setName("李四");
zhangsan.start();
lisi.start();
 }
}

Move.java

public class Move implements Runnable{
public void run() {
String name=Thread.currentThread().getName();
StringBuffer str=new StringBuffer();
for (int i = 0; i < 3; i++) {
if (name.equals("张三")) {
str.append(name);
System.out.println(name+"线程的局部变量i="+i+",str="+str);
}
else if (name.equals("李四")) {
str.append(name);
System.out.println(name+"线程的局部变量i="+i+",str="+str);
}
try {
Thread.sleep(2000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}

运行结果:

5.在线程中启动其他线程

线程通过调用star()方法将启动该线程,使其从新建状态进入就绪队列排队,一旦轮到他来享用cpu资源时,就可以脱离创建它的主线程进入自己的生命周期。

例如:在两个线程中共同完成1+2+3+4+5+6+7+8+9+10,一个线程完成1+2+3+4+5时启动另外一个线程。

Move.java

public class Move implements Runnable{
int i=1,sum=0;  //線程共享數據
public void run() {
Thread thread=Thread.currentThread();
System.out.println(thread.getName()+"开始计算");
while(i<=10){
sum=sum+i;
System.out.println(""+sum);
if (i==5) {
System.out.println(thread.getName()+"完成任务!i="+i);
Thread thread2=new Thread(this);//thread2與thread的目標對象相同
thread2.setName("李四");
thread2.start();      //啓動thread2;
i++;                  //死亡前將i變爲6
return;
}
i++;
try {
Thread.sleep(300);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
}

Demo10.java

public class Demo10 {
public static void main(String[] args) {
Move move=new Move();
Thread thread=new Thread(move);
thread.setName("張三");
thread.start();
}
}

结果:

6.总结线程中常用方法

(1)start()

(2)run()

(3)sleep(int millsecond)

(4)isAlive()

(5)currentThread()

(6)interrupt()

7.GUI线程

当Java程序包含图形用户界面是,Java虚拟机在运行应用程序的同时会自动启动更多的线程,其中两个重要的线程:AWT-EventQuecue和AWT-Windows。AWT-EventQuence线程负责处理GUI事件,AWT-windows负责处理将窗口或者组件绘画到桌面。jvm都会保证每个线程都会享受到cpu资源。

8.线程同步

在处理线程同步是,要做的第一件事 就是要把修改数据的方法用关键字synchronized来修饰。当一个线程A使用这个方法时,其他线程想要使用这个方法,必须等线程A先使用完。所谓线程同步,就是若干个线程需要使用一个synchronized修饰的方法。

9.在同步方法中使用wait()、notify()、notifyAll()方法

当一个线程中使用的同步方法中某些变量需要其他线程修改后才能使用,在同步方法这个使用wait()方法。使用wait方法可以中断方法的执行,使本线程等待,暂时让出cpu的使用权,并容许其他线程使用这个同步方法。其他线程如果知道不用等待,notifyAll()通知所有等待使用该同步方法的线程,结束等待。如果使用notify只通知等待中的某一个线程结束等待。

10.计时器线程Timer

当某些操作需要周期性地执行,就可以使用计时器。可以使用Timer类的构造方法Timer(int a,Object b)创建一个计时器,其中a为毫秒,b是计时器的监视器。计时器发生振铃事件是ActinEvent类型事件。当振铃事件发生时,监视器就会监视到这个事件,监视器就会回调ActionEvent接口中的actionPerformed(ActionEvent e)方法。计时器创建以后start(),启动计时器,stop结束计时器,restart()重新启动计时器。



  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值