Java中使用多线程
在java中要想实现多线程,有两种手段,一种是继续Thread类,另外一种是实现Runnable接口。
1、 继承Thread实现多线程
class hello extends Thread {
public hello() {
}
public hello(String name) {
this.name = name;
}
public void run() {
for (int i = 0; i < 5; i++) {
System.out.println(name + "
运行
" + i);
}
}
public static void main(String[] args) {
hello h1 = new hello("A");
hello h2 = new hello("B");
h1.start();
h2.start();
}
private String name;
}
2、 继承Runnable接口实现多线程
class hello implements Runnable {
public hello() {
}
public hello(String name) {
this.name = name;
}
public void run() {
for (int i = 0; i < 5; i++) {
System.out.println(name + "运行 " + i);
}
}
public static void main(String[] args) {
hello h1 = new hello("线程A");
Thread t1 = new Thread(h1);
hello h2 = new hello("线程B");
Thread t2 = new Thread(h2);
t1.start();
t2.start();
}
private String name;
}
这种方式,还有一种更简单的写法:
import java.lang.Thread;
public class test {
public static void main(String[] args) {
System.out.println("begin");
//启动一个线程
new Thread(new Runnable() {
@Override
public void run() {
System.out.println("thread proc...");
}
}).start();
}
}
两种实现方式的区别和联系:
在程序开发中只要是多线程肯定永远以实现Runnable接口为主,因为实现Runnable接口相比继承Thread类有如下好处:
->避免点继承的局限,一个类可以继承多个接口。
->适合于资源的共享
以卖票程序为例,通过Thread类完成:
package org.demo.dff;
class MyThread extends Thread{
private int ticket=10;
public void run(){
for(int i=0;i<20;i++){
if(this.ticket>0){
System.out.println("賣票:ticket"+this.ticket--);
}
}
}
};
下面通过三个线程对象,同时卖票:
package org.demo.dff;
public class ThreadTicket {
public static void main(String[] args) {
MyThread mt1=new MyThread();
MyThread mt2=new MyThread();
MyThread mt3=new MyThread();
mt1.start();//每个线程都各卖了10张,共卖了30张票
mt2.start();//但实际只有10张票,每个线程都卖自己的票
mt3.start();//没有达到资源共享
}
}
如果用Runnable就可以实现资源共享,下面看例子:
package org.demo.runnable;
class MyThread implements Runnable{
private int ticket=10;
public void run(){
for(int i=0;i<20;i++){
if(this.ticket>0){
System.out.println("賣票:ticket"+this.ticket--);
}
}
}
}
package org.demo.runnable;
public class RunnableTicket {
public static void main(String[] args) {
MyThread mt=new MyThread();
new Thread(mt).start();//同一个mt,但是在Thread中就不可以,如果用同一
new Thread(mt).start();//个实例化对象mt,就会出现异常
new Thread(mt).start();
}
};
虽然现在程序中有三个线程,但是一共卖了10张票,也就是说使用Runnable实现多线程可以达到资源共享目的。
线程的操作
设置线程为后台线程:setDaemon(true)
中断线程:interrupt()
线程同步:
【同步代码块】:
语法格式:
synchronized(同步对象){
//需要同步的代码
}
但是一般都把当前对象this作为同步对象。
class
hello implements
Runnable {
public
void
run() {
for
(int
i=0
;i<10
;++i){
synchronized
(this
) {
if
(count>0
){
try
{
Thread.sleep(1000
);
}catch
(InterruptedException e){
e.printStackTrace();
}
System.out.println(count--);
}
}
}
}
public
static
void
main(String[] args) {
hello he=new
hello();
Thread h1=new
Thread(he);
Thread h2=new
Thread(he);
Thread h3=new
Thread(he);
h1.start();
h2.start();
h3.start();
}
private
int
count=5
;
}
【同步方法】
也可以采用同步方法。
语法格式为synchronized 方法返回类型方法名(参数列表){
// 其他代码
}
class
hello implements
Runnable {
public
void
run() {
for
(int
i = 0
; i < 10
; ++i) {
sale();
}
}
public
synchronized
void
sale() {
if
(count > 0
) {
try
{
Thread.sleep(1000
);
} catch
(InterruptedException e) {
e.printStackTrace();
}
System.out.println(count--);
}
}
public
static
void
main(String[] args) {
hello he = new
hello();
Thread h1 = new
Thread(he);
Thread h2 = new
Thread(he);
Thread h3 = new
Thread(he);
h1.start();
h2.start();
h3.start();
}
private
int
count = 5
;
}
更多的线程同步需要参考Object.wait和Object.notify方法