Java多线程实现

Java中三种多线程的实现方式。

 

如果要想在Java中实现多线程有两种途径:

         ·继承Thread类;

         ·实现Runnable接口(Callable接口);

继承Thread类

package thread;
//线程操作主类
class MyThread extends Thread//这是一个多线程的操作类
{
	private String name ;
	public MyThread(String name)
	{
		this.name = name;
	}
	@Override
	public void run() {//覆写run()方法,作为线程的主体操作方法
		for(int x = 1 ; x < 51 ; x++)
		{
			System.out.println(this.name + "-->"+x);
		}
	}
}
public class ThreadTest 
{
	public static void main(String[] args) 
	{
		MyThread mt1 = new MyThread("线程A");
		MyThread mt2 = new MyThread("线程B");
		MyThread mt3 = new MyThread("线程C");
		
		mt1.start();
		mt2.start();
		mt3.start();
	}
}

结果

线程A-->42
线程A-->43
线程A-->44
线程A-->45
线程A-->46
线程B-->1
线程A-->47
线程B-->2
线程A-->48
线程B-->3
线程A-->49
线程B-->4
线程C-->1
线程C-->2
线程A-->50
线程C-->3
线程C-->4
线程C-->5

疑问?为什么多线程启动不是调用run()方法而是调用start()方法?

看下strat方法定义

public synchronized void start() {
        if (threadStatus != 0)
            throw new IllegalThreadStateException();//线程多次调用时抛出异常
        group.add(this);
        boolean started = false;
        try {
            start0();
            started = true;
        } finally {
            try {
                if (!started) {
                    group.threadStartFailed(this);
                }
            } catch (Throwable ignore) {
            }
        }
}
private native void start0();

    发现在strat方法里面调用了start0()方法,与抽象方法类似,但是使用了native声明。在Java里有JNI技术(Java Native Interface),特点:使用Java调用本机操作系统提供的函数。缺点是不能够离开特定的操作系统。

 

    如果要想线程能够执行,需要操作系统来进行资源分配,所以操作严格来讲主要是由JVM负责根据不同的操作系统而实现的 。

   即:使用Thread类的start()方法不仅仅要启动多线程的执行代码,还要去根据不同的操作系统进行资源的分配。

实现Runnable接口

package thread;
class MyThread implements Runnable//这是一个多线程的操作类
{
	private String name ;
	public MyThread(String name)
	{
		this.name = name;
	}
	@Override
	public void run() {//覆写run()方法,作为线程的主体操作方法
		for(int x = 1 ; x < 51 ; x++)
		{
			System.out.println(this.name + "-->"+x);
		}
	}
}
public class ThreadTest 
{
	public static void main(String[] args) 
	{
		MyThread mt1 = new MyThread("线程A");
		MyThread mt2 = new MyThread("线程B");
		MyThread mt3 = new MyThread("线程C");
		
		new Thread(mt1).start();
		new Thread(mt2).start();
		new Thread(mt3).start();
	}
}

 

(面试题)多线程两种实现方式的区别?

·使用Runnable接口Thread相比,解决了单继承的定义局限!

         ·Runnable接口实现的多线程可以比Thread类实现的多线程更加清楚的描述共享的概念。

 

public class Thread

extends Object

implements Runnable

@FunctionalInterface

public interface Runnable {

    public abstract void run();

}

 

第三种实现方法:

         Runnable接口实现多线程,其中的Run()方法不能返回结果,为了解决这样的矛盾,提供了一个新的接口Callable接口。

Callable接口

Package java.util.concurrent

Interface Callable<V>

@FunctionalInterface

public interface Callable<V> {

         V call() throws Exception;

}

java.util.concurrent

Interface Future<V>

java.util.concurrent.FutureTask<V>

public class FutureTask<V>

extends Object

implements RunnableFuture<V>

public interface RunnableFuture<V>

extends Runnable, Future<V>

 

package thread;
import java.util.concurrent.Callable;
import java.util.concurrent.FutureTask;
/**
 * 使用Callable实现多线程
 * 2017-10-07
 * @author Junwei Zhu
 *
 */
class MyThread02 implements Callable<String>{
	private int ticket = 10 ;
	@Override
	public String call() throws Exception {
		for(int x = 0 ; x < 100 ; x ++)
		{
			if(this.ticket>0)
				System.out.println("卖票,ticket:"+this.ticket--);
		}
		return "票已卖光。" ;
	}
	
}
public class CallableTest {
	public static void main(String[] args) throws Exception {
		MyThread02 mt1 = new MyThread02();
		MyThread02 mt2 = new MyThread02();
		//目的是取得call()返回结果
		FutureTask<String> task1 = new FutureTask<String>(mt1);
		FutureTask<String> task2 = new FutureTask<String>(mt2);
		//FutureTask是Runnable接口子类,所以可以使用Thread类的构造来接收task对象
		new Thread(task1).start();//启动多线程
		new Thread(task2).start();
		//多线程执行完毕后可以取得内容,依靠FutureTask中的Future中的get()方法完成
		System.out.println("A线程的返回结果:"+task1.get());
		System.out.println("B线程的返回结果:"+task2.get());
	}
}

结果:

卖票,ticket:10
卖票,ticket:9
卖票,ticket:8
卖票,ticket:8
卖票,ticket:7
卖票,ticket:6
卖票,ticket:7
卖票,ticket:5
卖票,ticket:6
卖票,ticket:5
卖票,ticket:4
卖票,ticket:4
卖票,ticket:3
卖票,ticket:3
卖票,ticket:2
卖票,ticket:1
卖票,ticket:2
A线程的返回结果:票已卖光。
卖票,ticket:1
B线程的返回结果:票已卖光。

 

posted @ 2018-06-29 11:34  雨中遐想  阅读(3)  评论(0编辑  收藏  举报  来源