1.如果在类里要激活线程,必须先做好下面两个准备:
(1)线程必须扩展自 Thread 类,使自己成为它的子类。
(2)线程的处理必须编写在 run()方法内。
2.多线程的定义语法
class 类名称 extends Thread // 从 Thread 类扩展出子类
{
属性
方法…
修饰符 run(){ // 复写 Thread 类里的 run()方法
以线程处理的程序;
}
}
3. 要启动线程必须调用 Thread类之中的 start()方法,而调用了 start()方法,也就是调用了 run()方法。
4. Java 中如果一个类继承了某一个类,同时又想采用多线程技术的时, 就不能用 Thread 类产生线程, 因为 Java 不允许多继承, 这时就要用 Runnable接口来创建线程了。
5.多线程的定义语法
class 类名称 implements Runnable // 实现 Runnable 接口
{
属性
方法…
修饰符 run(){ // 复写 Thread 类里的 run()方法以线程处理的程序;
}
}
6.实现 Runnable 接口相对于继承 Thread 类来说,有如下显著的优势:
(1) 适合多个相同程序代码的线程去处理同一资源的情况,把虚拟 CPU(线程)同程序的代码、数据有效分离,较好地体现了面向对象的设计思想。
(2)可以避免由于 Java 的单继承特性带来的局限。 开发中经常碰到这样一种
情况,即:当要将已经继承了某一个类的子类放入多线程中,由于一个类不能同时有两个父类,所以不能用继承 Thread 类的方式,那么就只能采用实现 Runnable 接口的方式了。
(3)增强了程序的健壮性, 代码能够被多个线程共享, 代码与数据是独立的。
当多个线程的执行代码来自同一个类的实例时,即称它们共享相同的代码。多个线程可以操作相同的数据,与它们的代码无关。当共享访问相同的对象时,即共享相同的数据。当线程被构造时,需要的代码和数据通过一个对象作为构造函数实参传递进去,这个对象就是一个实现了Runnable 接口的类的实例。
事实上,几乎所有多线程应用都可用第二种方式,即实现 Runnable 接口。
7.任何线程一般具有五种状态,即创建、就绪、运行、阻塞、终止。
(1)新建状态
在程序中用构造方法创建了一个线程对象后,新的线程对象便处于新建状态,此
时,它已经有了相应的内存空间和其它资源,但还处于不可运行状态。新建一个线程对象可采用线程构造方法来实现。
例如: Thread thread=new Thread();
(2)就绪状态
新建线程对象后,调用该线程的 start()方法就可以启动线程。当线程启动时,线
程进入就绪状态。此时,线程将进入线程队列排队,等待 CPU 服务,这表明它已经具备了运行条件。
(3)运行状态
当就绪状态的线程被调用并获得处理器资源时,线程就进入了运行状态。此时,
自动调用该线程对象的 run()方法。run()方法定义了该线程的操作和功能。
(4)堵塞状态
一个正在执行的线程在某些特殊情况下,如被人为挂起或需要执行耗时的输入输
出操作时,将让出 CPU 并暂时中止自己的执行,进入堵塞状态。在可执行状态下,如果调用 sleep()、suspend()、wait()等方法,线程都将进入堵塞状态。堵塞时,线程不能进入排队队列,只有当引起堵塞的原因被消除后,线程才可以转入就绪状态。
(5)死亡状态
线程调用 stop()方法时或 run()方法执行结束后,线程即处于死亡状态。处于死亡状态的线程不具有继续运行的能力。
8.Thread 类中的主要方法
方法名称 方法说明
public static int activeCount() 返回线程组中目前活动的线程的数目
public static native Thread currentThread() 返回目前正在执行的线程
public void destroy() 销毁线程
public static int enumerate(Thread tarray[]) 将当前和子线程组中的活动线程拷贝至指定的线程数组
public final String getName() 返回线程的名称
public final int getPriority() 返回线程的优先级
public final ThreadGroup getThreadGroup() 返回线程的线程组
public static boolean interrupted() 判断目前线程是否被中断,如果是,返
回 true,否则返回 false
public final native boolean isAlive()判断线程是否在活动,如果是,返回
true,否则返回 false
public boolean isInterrupted() 判断目前线程是否被中断,如果是,返
回 true,否则返回 false
public final void join() throws InterruptedException 等待线程死亡
public final synchronized void join(long millis)throws InterruptedException
等待 millis 毫秒后,线程死亡
public final synchronized void join(long
millis,int nanos) throws InterruptedException 等待 millis 毫秒加上 nanos 微秒后,线程死亡
public void run() 执行线程
public final void setName() 设定线程名称
public final void setPriority(int newPriority) 设定线程的优先值
public static native void sleep(long millis)
throws InterruptedException
使目前正在执行的线程休眠 millis 毫秒
public static void sleep(long millis,int nanos)throws InterruptedException 使目前正在执行的线程休眠 millis 毫秒加上 nanos 微秒
public native synchronized void start() 开始执行线程
public String toString() 返回代表线程的字符串
public static native void yield()将目前正在执行的线程暂停,允许其它
线程执行。
9.如果某个线程对象在启动(调用 start()方法)之前调用了 setDaemon(true)方法,这个线程就变成了后台线程。
10.Thread.sleep()方法迫使线程执行到该处后暂停执行,让出 CPU 给别
的线程,在指定的时间(这里是毫秒)后,CPU 回到刚才暂停的线程上执行。
11.线程同步:当一个线程运行到 if(tickets>0)后, CPU 不去执行其它线程中的、 可能影响当前线程中的下一句代码的执行结果的代码块,必须等到下一句执行完后才能去执行其它线程中的有关代码块。这段代码就好比一座独木桥,任何时刻,都只能有一个人在桥上行走,程序中不能有多个线程同时在这两句代码之间执行,这就是线程同步。
12.同步代码块定义语法
…
synchronized(对象)
{
需要同步的代码 ;
}
…
13.除了可以对代码块进行同步外,也可以对函数实现同步,只要在需要同步的函数定义前加上 synchronized 关键字即可。
同步方法定义语法:
访问控制符 synchronized 返回值类型 方法名称(参数)
{
....;
}
14.一旦有多个进程, 且它们都要争用对多个锁的独占访问, 那么就有可能发生死锁。如果有一组进程或线程,其中每个都在等待一个只有其它进程或线程才可以执行的操作,那么就称它们被死锁了。
15.要避免死锁, 应该确保在获取多个锁时, 在所有的线程中都以相同的顺序获取锁.
16.线程间通讯
(1)这就是资源不同步的与原因,可以在 P 类中增加两个同步方法:set()和 get();
(2) Java 是通过 Object 类的 wait、 notify、 notifyAll
这几个方法来实现线程间的通信的,又因为所有的类都是从 Object 继承的,所以任何类都可以直接使用这些方法。下面是这三个方法的简要说明:
wait:告诉当前线程放弃监视器并进入睡眠状态,直到其它线程进入同一监视器
并调用 notify 为止。
notify:唤醒同一对象监视器中调用 wait 的第一个线程。类似排队买票,一个人
买完之后,后面的人可以继续买。
notifyAll:唤醒同一对象监视器中调用 wait 的所有线程,具有最高优先级的线程首先被唤醒并执行。
(3)wait、notify、notifyAll 这三个方法只能在 synchronized 方法中调用,即无论线程调用一个对象的 wait 还是 notify 方法, 该线程必须先得到该对象的锁标记, 这样, notify只能唤醒同一对象监视器中调用 wait 的线程,使用多个对象监视器,就可以分别有多个 wait、notify 的情况,同组里的 wait 只能被同组的 notify 唤醒。
17.
1、 线程(thread)是指程序的运行流程。 “多线程”的机制可以同时运行多个程序块,使程序运行的效率更高,也解决了传统程序设计语言所无法解决的问题。
2、 如果在类里要激活线程,必须先做好下面两项准备:
(1) 此类必须是扩展自 Thread 类,使自己成为它的子类。
(2) 线程的处理必须编写在 run()方法内。
3、 run()方法是定义在 Thread 类里的一个方法,因此把线程的程序代码编写在 run()方法内,所做的就是覆盖的操作。
4、 Runnable 接口里声明了抽象的 run()方法,因此必须在实现 Runnable 接口的类里明确定义 run()方法。
5、 每一个线程,在其创建和消亡之前,均会处于下列五种状态之一:创建、就绪、
运行、阻塞、终止。
6、 暂停状态的线程可由下列的情况所产生:
(1)该线程调用对象的 wait()时。
(2)该线程本身调用 sleep()时。
(3)该线程和另一个线程 join()在一起时。
7、 被冻结因素消失的原因有:
(1) 如果线程是由调用对象的 wait()方法所冻结, 则该对象的 notify()方法被调用时可解除冻结。
(2)线程进入休眠(sleep)状态,但指定的休眠时间到了。
8、 当线程的 run()方法运行结束,或是由线程调用它的 stop()方法时,则线程进入消亡状态。
9、 Thread 类里的 sleep()方法可用来控制线程的休眠状态,休眠的时间要视 sleep()里的参数而定。
10、要强制某一线程运行,可用 join()方法。
11、join()方法会抛出 InterruptedException 的异常,所以编写时必须把 join()方法编写在 try-catch 块内。
12、当多个线程对象操纵同一共享资源时,要使用 synchronized 关键字来进行资源的同步处理。
(1)线程必须扩展自 Thread 类,使自己成为它的子类。
(2)线程的处理必须编写在 run()方法内。
2.多线程的定义语法
class 类名称 extends Thread // 从 Thread 类扩展出子类
{
属性
方法…
修饰符 run(){ // 复写 Thread 类里的 run()方法
以线程处理的程序;
}
}
3. 要启动线程必须调用 Thread类之中的 start()方法,而调用了 start()方法,也就是调用了 run()方法。
4. Java 中如果一个类继承了某一个类,同时又想采用多线程技术的时, 就不能用 Thread 类产生线程, 因为 Java 不允许多继承, 这时就要用 Runnable接口来创建线程了。
5.多线程的定义语法
class 类名称 implements Runnable // 实现 Runnable 接口
{
属性
方法…
修饰符 run(){ // 复写 Thread 类里的 run()方法以线程处理的程序;
}
}
6.实现 Runnable 接口相对于继承 Thread 类来说,有如下显著的优势:
(1) 适合多个相同程序代码的线程去处理同一资源的情况,把虚拟 CPU(线程)同程序的代码、数据有效分离,较好地体现了面向对象的设计思想。
(2)可以避免由于 Java 的单继承特性带来的局限。 开发中经常碰到这样一种
情况,即:当要将已经继承了某一个类的子类放入多线程中,由于一个类不能同时有两个父类,所以不能用继承 Thread 类的方式,那么就只能采用实现 Runnable 接口的方式了。
(3)增强了程序的健壮性, 代码能够被多个线程共享, 代码与数据是独立的。
当多个线程的执行代码来自同一个类的实例时,即称它们共享相同的代码。多个线程可以操作相同的数据,与它们的代码无关。当共享访问相同的对象时,即共享相同的数据。当线程被构造时,需要的代码和数据通过一个对象作为构造函数实参传递进去,这个对象就是一个实现了Runnable 接口的类的实例。
事实上,几乎所有多线程应用都可用第二种方式,即实现 Runnable 接口。
7.任何线程一般具有五种状态,即创建、就绪、运行、阻塞、终止。
(1)新建状态
在程序中用构造方法创建了一个线程对象后,新的线程对象便处于新建状态,此
时,它已经有了相应的内存空间和其它资源,但还处于不可运行状态。新建一个线程对象可采用线程构造方法来实现。
例如: Thread thread=new Thread();
(2)就绪状态
新建线程对象后,调用该线程的 start()方法就可以启动线程。当线程启动时,线
程进入就绪状态。此时,线程将进入线程队列排队,等待 CPU 服务,这表明它已经具备了运行条件。
(3)运行状态
当就绪状态的线程被调用并获得处理器资源时,线程就进入了运行状态。此时,
自动调用该线程对象的 run()方法。run()方法定义了该线程的操作和功能。
(4)堵塞状态
一个正在执行的线程在某些特殊情况下,如被人为挂起或需要执行耗时的输入输
出操作时,将让出 CPU 并暂时中止自己的执行,进入堵塞状态。在可执行状态下,如果调用 sleep()、suspend()、wait()等方法,线程都将进入堵塞状态。堵塞时,线程不能进入排队队列,只有当引起堵塞的原因被消除后,线程才可以转入就绪状态。
(5)死亡状态
线程调用 stop()方法时或 run()方法执行结束后,线程即处于死亡状态。处于死亡状态的线程不具有继续运行的能力。
8.Thread 类中的主要方法
方法名称 方法说明
public static int activeCount() 返回线程组中目前活动的线程的数目
public static native Thread currentThread() 返回目前正在执行的线程
public void destroy() 销毁线程
public static int enumerate(Thread tarray[]) 将当前和子线程组中的活动线程拷贝至指定的线程数组
public final String getName() 返回线程的名称
public final int getPriority() 返回线程的优先级
public final ThreadGroup getThreadGroup() 返回线程的线程组
public static boolean interrupted() 判断目前线程是否被中断,如果是,返
回 true,否则返回 false
public final native boolean isAlive()判断线程是否在活动,如果是,返回
true,否则返回 false
public boolean isInterrupted() 判断目前线程是否被中断,如果是,返
回 true,否则返回 false
public final void join() throws InterruptedException 等待线程死亡
public final synchronized void join(long millis)throws InterruptedException
等待 millis 毫秒后,线程死亡
public final synchronized void join(long
millis,int nanos) throws InterruptedException 等待 millis 毫秒加上 nanos 微秒后,线程死亡
public void run() 执行线程
public final void setName() 设定线程名称
public final void setPriority(int newPriority) 设定线程的优先值
public static native void sleep(long millis)
throws InterruptedException
使目前正在执行的线程休眠 millis 毫秒
public static void sleep(long millis,int nanos)throws InterruptedException 使目前正在执行的线程休眠 millis 毫秒加上 nanos 微秒
public native synchronized void start() 开始执行线程
public String toString() 返回代表线程的字符串
public static native void yield()将目前正在执行的线程暂停,允许其它
线程执行。
9.如果某个线程对象在启动(调用 start()方法)之前调用了 setDaemon(true)方法,这个线程就变成了后台线程。
10.Thread.sleep()方法迫使线程执行到该处后暂停执行,让出 CPU 给别
的线程,在指定的时间(这里是毫秒)后,CPU 回到刚才暂停的线程上执行。
11.线程同步:当一个线程运行到 if(tickets>0)后, CPU 不去执行其它线程中的、 可能影响当前线程中的下一句代码的执行结果的代码块,必须等到下一句执行完后才能去执行其它线程中的有关代码块。这段代码就好比一座独木桥,任何时刻,都只能有一个人在桥上行走,程序中不能有多个线程同时在这两句代码之间执行,这就是线程同步。
12.同步代码块定义语法
…
synchronized(对象)
{
需要同步的代码 ;
}
…
13.除了可以对代码块进行同步外,也可以对函数实现同步,只要在需要同步的函数定义前加上 synchronized 关键字即可。
同步方法定义语法:
访问控制符 synchronized 返回值类型 方法名称(参数)
{
....;
}
14.一旦有多个进程, 且它们都要争用对多个锁的独占访问, 那么就有可能发生死锁。如果有一组进程或线程,其中每个都在等待一个只有其它进程或线程才可以执行的操作,那么就称它们被死锁了。
15.要避免死锁, 应该确保在获取多个锁时, 在所有的线程中都以相同的顺序获取锁.
16.线程间通讯
(1)这就是资源不同步的与原因,可以在 P 类中增加两个同步方法:set()和 get();
(2) Java 是通过 Object 类的 wait、 notify、 notifyAll
这几个方法来实现线程间的通信的,又因为所有的类都是从 Object 继承的,所以任何类都可以直接使用这些方法。下面是这三个方法的简要说明:
wait:告诉当前线程放弃监视器并进入睡眠状态,直到其它线程进入同一监视器
并调用 notify 为止。
notify:唤醒同一对象监视器中调用 wait 的第一个线程。类似排队买票,一个人
买完之后,后面的人可以继续买。
notifyAll:唤醒同一对象监视器中调用 wait 的所有线程,具有最高优先级的线程首先被唤醒并执行。
(3)wait、notify、notifyAll 这三个方法只能在 synchronized 方法中调用,即无论线程调用一个对象的 wait 还是 notify 方法, 该线程必须先得到该对象的锁标记, 这样, notify只能唤醒同一对象监视器中调用 wait 的线程,使用多个对象监视器,就可以分别有多个 wait、notify 的情况,同组里的 wait 只能被同组的 notify 唤醒。
17.
1、 线程(thread)是指程序的运行流程。 “多线程”的机制可以同时运行多个程序块,使程序运行的效率更高,也解决了传统程序设计语言所无法解决的问题。
2、 如果在类里要激活线程,必须先做好下面两项准备:
(1) 此类必须是扩展自 Thread 类,使自己成为它的子类。
(2) 线程的处理必须编写在 run()方法内。
3、 run()方法是定义在 Thread 类里的一个方法,因此把线程的程序代码编写在 run()方法内,所做的就是覆盖的操作。
4、 Runnable 接口里声明了抽象的 run()方法,因此必须在实现 Runnable 接口的类里明确定义 run()方法。
5、 每一个线程,在其创建和消亡之前,均会处于下列五种状态之一:创建、就绪、
运行、阻塞、终止。
6、 暂停状态的线程可由下列的情况所产生:
(1)该线程调用对象的 wait()时。
(2)该线程本身调用 sleep()时。
(3)该线程和另一个线程 join()在一起时。
7、 被冻结因素消失的原因有:
(1) 如果线程是由调用对象的 wait()方法所冻结, 则该对象的 notify()方法被调用时可解除冻结。
(2)线程进入休眠(sleep)状态,但指定的休眠时间到了。
8、 当线程的 run()方法运行结束,或是由线程调用它的 stop()方法时,则线程进入消亡状态。
9、 Thread 类里的 sleep()方法可用来控制线程的休眠状态,休眠的时间要视 sleep()里的参数而定。
10、要强制某一线程运行,可用 join()方法。
11、join()方法会抛出 InterruptedException 的异常,所以编写时必须把 join()方法编写在 try-catch 块内。
12、当多个线程对象操纵同一共享资源时,要使用 synchronized 关键字来进行资源的同步处理。