java中的多线程
来源:互联网 发布:图书编辑 知乎 编辑:程序博客网 时间:2024/06/15 21:23
java多线程实现有两种方式,一种是继成Thread类,另外一种是实现Runable接口。
对于直接继承Thread的类来说,代码大致框架是:
class
类名
extends
Thread{
方法
1
;
方法
2
;
…
public
void
run(){
// other code…
}
属性
1
;
属性
2
;
…
}
主函数:
public
static
void
main(String[] args) {
Class
h1=
new
Class
(
"A"
);
Class
h2=
new
Class
(
"B"
);
h1.start();
h2.start();
}
实现Runable接口,代码大致框架是:
大致框架是:
class
类名
implements
Runnable{
方法
1
;
方法
2
;
…
public
void
run(){
// other code…
}
属性
1
;
属性
2
;
…
}
主函数:
public
static
void
main(String[] args) {
Class
h1=
new
Class
(
"A"
);
Thread demo1=
new
Thread(h1);
Class
h2=
new
Class
(
"B"
);
Thread demo2=
new
Thread(h2);
demo1
.start();
demo2
.start();
}
可见两者在主函数的调用有所区别。
Thread和Runnable的区别:
如果一个类继承Thread,则不适合资源共享。但是如果实现了Runable接口的话,则很容易的实现资源共享。
总结一下吧:
实现Runnable接口比继承Thread类所具有的优势:
1):适合多个相同的程序代码的线程去处理同一个资源
2):可以避免java中的单继承的限制
3):增加程序的健壮性,代码可以被多个线程共享,代码和数据独立。
概述:线程的挂起操作实质上就是使线程进入“非可执行”状态下,在这个状态下CPU不会分给线程时间片,进入这个状态可以用来暂停一个线程的运行。在线程挂起后,可以通过重新唤醒线程来使之恢复运行。
当一个线程进入“非可执行”状态,必然存在某种原因使其不能继续运行,这些原因可能是如下几种情况:
A,通过调用sleep()方法使线程进入休眠状态,线程在指定时间内不会运行。
B,通过调用join()方法使线程挂起,如果某个线程在另一个线程t上调用t.join(),这个线程将被挂起,直到线程t执行完毕为止。
C,通过调用wait()方法使线程挂起,直到线程得到了notify()和notifyAll()消息,线程才会进入“可执行”状态。
(1)sleep()方法:是一个使线程暂时停止一段执行时间的方法,该时间由给定的毫秒数决定。下面演示一个使用sleep()方法的例子,如下。
- class ThreadA extends Thread
- {
- public void run(){
- System.out.println("ThreadA is running");
- }
- }
- public class TestNew {
- public static void main(String[] args)throws InterruptedException {
- // TODO Auto-generated method stub
- ThreadA ta = new ThreadA();
- ta.start();
- ta.sleep(5000);
- System.out.println("TestNew is running");
- }
- }
(2)join()方法:能够使当前执行的线程停下来等待,直至join()方法所调用的那个线程结束,再恢复执行。例如如果有一个线程A正在运行,用户希望插入一个线程B,并且要求线程B执行完毕,然后再继续线程A,此时可以使用join()方法来完成这个需求。
- public class TestNew extends Thread
- {
- public static int a = 0;
- public void run(){
- for(int k = 0;k < 5;k ++){
- a = a + 1;
- }
- }
- public static void main(String[] args)throws InterruptedException {
- // TODO Auto-generated method stub
- TestNew ta = new TestNew();
- ta.start();
- ta.join();
- System.out.println(String.valueOf(a));
- }
- }
执行结果:5。ta线程执行完毕后,才会开始打印a。如果没有join(),则结果不一定是5,原因是ta线程跟main线程的执行顺序并不固定。
(3)wait()与notify()方法:wait()方法同样可以使线程进行挂起操作,调用了wait()方法的线程进入了“非可执行”状态,使用wait()方法有两种方式,例如:
thread.wait(1000);
或:
thread.wait();
thread.notify();
其中第一种方式给定线程挂起时间,基本上与sleep()方法用法相同。第二种方式是wait()与notify()方法配合使用,这种方式让wait()方法无限等下去,直到线程接收到notify()或notifyAll()消息为止。
wait()、notify()、notifyAll()不同于其他线程方法,这3个方法是java.lang.Object类的一部分,所以在定义自己类时会继承下来。wait()、notify()、notifyAll()都被声明为final类,所以无法重新定义。
(4)suspend()与resume()方法
有时更好地挂起方法是强制挂起线程,而不是为线程指定休眠时间,这种情况下由其他线程负责唤醒其继续执行,除了wait()与notify()方法之外,线程中还有一对方法用于完成此功能,这就是suspend()与resume()方法。thread.suspend();thread.resume(),线程thread在运行到suspend()之后被强制挂起,暂停运行,直到主线程调用thread.resume()方法时才被重新唤醒。
Java2中已经废弃了suspend()和resume()方法,因为使用这两个方法可能会产生死锁,所以应该使用同步对象调用wait()和notify()的机制来代替suspend()和resume()进行线程控制。
实现同步机制有两个方法:
1)同步代码块:
synchronized(同一个数据){} 同一个数据:就是N条线程同时访问一个数据。
2)
同步方法:
public synchronized 数据返回类型 方法名(){}
就是使用 synchronized 来修饰某个方法,则该方法称为同步方法。对于同步方法而言,无需显示指定同步监视器,同步方法的同步监视器是 this 也就是该对象的本身(这里指的对象本身有点含糊,其实就是调用该同步方法的对象)通过使用同步方法,可非常方便的将某类变成线程安全的类,具有如下特征:
1,该类的对象可以被多个线程安全的访问。
2,每个线程调用该对象的任意方法之后,都将得到正确的结果。
3,每个线程调用该对象的任意方法之后,该对象状态依然保持合理状态。
注:synchronized关键字可以修饰方法,也可以修饰代码块,但不能修饰构造器,属性等。
实现同步机制注意以下几点: 安全性高,性能低,在多线程用。性能高,安全性低,在单线程用。
1,不要对线程安全类的所有方法都进行同步,只对那些会改变共享资源方法的进行同步。
2,如果可变类有两种运行环境,当线程环境和多线程环境则应该为该可变类提供两种版本:线程安全版本和线程不安全版本(没有同步方法和同步块)。在单线程中环境中,使用线程不安全版本以保证性能,在多线程中使用线程安全版本.
- Java 程序中的多线程
- Java 程序中的多线程
- Java 程序中的多线程
- Java程序中的多线程
- java中的多线程
- Java中的多线程(一)
- Java 程序中的多线程
- Java中的多线程程序设计
- Java 程序中的多线程
- Java 程序中的多线程
- Java 程序中的多线程
- Java 程序中的多线程
- Java 程序中的多线程
- 再忆Java中的多线程
- Java中的多线程
- Java中的多线程
- Java中的多线程编程
- Java中的多线程编程
- Java之于反射
- bootstrap jquery.slimscroll
- android中图片的三级缓存cache策略(内存/文件/网络)
- 数据结构栈及其用法(C语言实现)
- Windows 已在 test.exe 中触发一个断点。 其原因可能是堆被损坏
- java中的多线程
- Java调用本地接口常见错误
- cf 46-d (模拟区间覆盖)
- java 布局管理
- 3.23
- Window下使用eclipse连接hadoop报错
- 如何保存ssh的主机名和用户名
- 在Servlet中使用开源fileupload包实现文件上传功能
- ubutun 14.04 从源代码编译 ngspice