JAVA学习笔记(三十二)

认识多线程


1.1 进程与线程


dos系统有一个非常明显的缺点,只要一中病毒之后系统会立刻死

机,因为传统的dos系统采用单进程的处理方式,所以只能有一个

程序独自运行,其他程序无法运行。


windows采用的事多进程的处理方式,在同一时间段同时运行多个

程序。


线程实际上就是在进程基础上的进一步划分。当然,会同时存在多

个线程。


如果一个进程没有了,则线程肯定会消失;
如果线程消失了,进程未必消失。
所有的线程都是在进程的基础上并发执行的。


进程是程序的一次动态执行过程,它经历了从代码加载,执行到执

行完毕的一个完整过程,这个过程也是进程本身从产生到最终消亡

的过程。


多线程是实现并发机制的一种有效手段。二者都是并发执行的一个

基本单位。


如果现在同时运行多个任务,则所有的系统资源都是共享的,被所

有线程所共有,但是程序处理需要CPU,传统的单核CPu,在同一个

时间段上会有多个程序执行,但是在同一时间点上只能存在一个程

序运行,也就是说,所有的程序都要抢占CPU资源。

但是现在的CPU已经发展到多核的状态了,在一个电脑上可能会存

在多个cpu。


1.2 java的多线程实现


在java中实现多线程的方式有两种:

:继承THread类

:实现Runnable接口

1.3

线程 是程序中的执行线程。Java 虚拟机允许应用程序并发地运行

多个执行线程。

每个线程都有一个优先级,高优先级线程的执行优先于低优先级线

程。每个线程都可以或不可以标记为一个守护程序。当某个线程中

运行的代码创建一个新 Thread 对象时,该新线程的初始优先级被

设定为创建线程的优先级,并且当且仅当创建线程是守护线程时,

新线程才是守护程序。

当 Java 虚拟机启动时,通常都会有单个非守护线程(它通常会调

用某个指定类的 main 方法)。Java 虚拟机会继续执行线程,直

到下列任一情况出现时为止:

调用了 Runtime 类的 exit 方法,并且安全管理器允许退出操作

发生。
非守护线程的所有线程都已停止运行,无论是通过从对 run 方法

的调用中返回,还是通过抛出一个传播到 run 方法之外的异常。
创建新执行线程有两种方法。一种方法是将类声明为 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();
每个线程都有一个标识名,多个线程可以同名。如果线程创建时

没有指定标识名,就会为其生成一个新名称。

从以下版本开始:
JDK1.0

1.4 A:THread类

THread类是在java.lang包中定义的,java.lang.Thread
,java.lang包会在程序运行时自动导入,所以无需手工编写imprt

语句。

一个类继承了Thread类之后,那么此类就具备了多线程的操作功能
在THread类中必须明确的覆写THread类中的run()方法 ,此方法

为线程的主体。

多线程的定义:

class 类名称 extends THread{
属性:
方法:

public void run()
{
线程主体;
}
}


class MyThread extends Thread
{
private String name;
public MyThread(String name){
this.name = name;
}
public void run(){
for( int i = 0;i < 10;i ++){
System.out.println(name+"运行:i="+i);
}
}
};
public class ThreadDemo01
{
public static void main(String args[]){
MyThread th1 = new MyThread("线程A:");
MyThread th2 = new MyThread("线程B:");
th1.run();
th2.run();
}
}

结果:

F:\java\thread>java ThreadDemo01
线程A:运行:i=0
线程A:运行:i=1
线程A:运行:i=2
线程A:运行:i=3
线程A:运行:i=4
线程A:运行:i=5
线程A:运行:i=6
线程A:运行:i=7
线程A:运行:i=8
线程A:运行:i=9
线程B:运行:i=0
线程B:运行:i=1
线程B:运行:i=2
线程B:运行:i=3
线程B:运行:i=4
线程B:运行:i=5
线程B:运行:i=6
线程B:运行:i=7
线程B:运行:i=8
线程B:运行:i=9

问题:以上的程序是先执行A后在执行B,并没有并发执行;
因为以上的程序还是按照古老的形式调用的,但是如果要启动一个

线程,必须使用thread类中定义的srart()方法。

一旦调用start()方法,实际上最终调用的就死run()方法。

startpublic void start()

使该线程开始执行;Java 虚拟机调用该线程的 run 方法。
结果是两个线程并发地运行;当前线程(从调用返回给 start 方

法)和另一个线程(执行其 run 方法)。

多次启动一个线程是非法的。特别是当线程已经结束执行后,不能

再重新启动。


run
public void run()

如果该线程是使用独立的 Runnable 运行对象构造的,则调用该

Runnable 对象的 run 方法;否则,该方法不执行任何操作并返回


Thread 的子类应该重写该方法。


class MyThread extends Thread
{
private String name;
public MyThread(String name){
this.name = name;
}
public void run(){
for( int i = 0;i < 10;i ++){
System.out.println(name+"运行:i="+i);
}
}
};
public class ThreadDemo01
{
public static void main(String args[]){
MyThread th1 = new MyThread("线程A:");
MyThread th2 = new MyThread("线程B:");
th1.start();
th2.start();
}
}

结果:

F:\java\thread>java ThreadDemo01
线程A:运行:i=0
线程B:运行:i=0
线程A:运行:i=1
线程B:运行:i=1
线程A:运行:i=2
线程B:运行:i=2
线程A:运行:i=3
线程B:运行:i=3
线程A:运行:i=4
线程B:运行:i=4
线程A:运行:i=5
线程B:运行:i=5
线程A:运行:i=6
线程B:运行:i=6
线程A:运行:i=7
线程B:运行:i=7
线程A:运行:i=8
线程B:运行:i=8
线程A:运行:i=9
线程B:运行:i=9


那么:


问什么不直接调用run()方法,而是通过start()方法调用呢?


查看thread类的定义,在JDK中的src.zip中全部都输java的源程序

代码,直接找到java.lang.Thread类,就可以打开Thread类的定义

public synchronized void start() {
/**
* This method is not invoked for the main method

thread or "system"
* group threads created/set up by the VM. Any new

functionality added
* to this method in the future may have to also

be added to the VM.
*
* A zero status value corresponds to state "NEW".
*/
if (threadStatus != 0 || this != me)
throw new IllegalThreadStateException();
group.add(this);
start0();
if (stopBeforeStart) {
stop0(throwableFromStop);
}
}


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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值