JAVA 实现多线程

继承 Thread 类创建线程类


public class MyThread extends Thread{
    int i=0;
    public void run(){
        for(;i<10;i++){
            System.out.println(getName()+" "+i);
        }
    }
    public static void main(String[] args){
        // 无参数构造器,调用自身的资源,资源不能共享
        new MyThread().start(); 
        new MyThread().start();
    }
}

输出结果:


Thread-1 0
Thread-1 1
Thread-1 2
Thread-1 3
Thread-1 4
Thread-1 5
Thread-1 6
Thread-0 1
Thread-0 2
Thread-0 3
Thread-0 4
Thread-0 5
Thread-0 6
Thread-0 7
Thread-0 8
Thread-1 7
Thread-1 8
Thread-1 9
Thread-0 9

要用 start() 方法启动线程,不能直接调用 run() 方法,直接调用 run() 方法就是普通的方法调用,而不是启动线程。


别的文章都说继承 Thread 类不能实现资源共享,那是因为他们启动的两个线程本身就是使用不同的资源,上面的代码就是使用不同的资源,下面实现一个使用同一个资源的 Thread 类


class Integer {
	public int num;
	public Integer(int num){
		this.num=num;
	}
}
class MyThread extends Thread {
	Integer a;
	public MyThread(Integer b){
		a=b;
	}
	public void run(){
		for(;a.num<10;){
			a.num++;
			System.out.println(getName()+" "+a.num);
		}
	}	
	public static void main(String[] args){
		Integer num=new Integer(0);
		// 使用带参数的构造器,调用同一个资源,实现资源共享
		new MyThread(num).start();
		new MyThread(num).start();
	}
}
输出结果:


Thread-0 1
Thread-0 2
Thread-0 3
Thread-1 4
Thread-0 5
Thread-1 6
Thread-0 7
Thread-1 8
Thread-0 9
Thread-1 10


实现Runnable接口创建线程类


public class MyRunnable implements Runnable {
    int i=0;
    public void run(){
        for(;i<10;i++){
            System.out.println(getName()+" "+i);
        }
    }
    public static void main(String[] args){
        MyRunnable t = new MyRunnable () ;
        // 带参数构造器,调用同一个 Runnable 对象,实现资源共享
        new Thread(t).start(); 
        new Thread(t).start();
    }
}

输出结果:

Thread-1 0
Thread-0 0
Thread-1 1
Thread-0 2
Thread-1 3
Thread-0 4
Thread-1 5
Thread-0 6
Thread-1 7
Thread-0 8
Thread-1 9



实现Callable接口创建线程类


// Callable 接口提供了 call() 方法作为线程执行体,该方法有返回值,可以抛出异常
public class MyCallable implements Callable<String>{
    public String call(){
        System.out.println(Thread.currentThread().getName());
        return "线程执行结束";
    }
    public static void main(String[] args){
        MyCallable t=new MyCallable();
        // 使用 FutureTask 来包装 Callable 对象,该类可以获得 call() 方法的返回值
        FutureTask<String> task=new FutureTask<String>(t);
        //实质还是以 Callable 对象来创建线程
        new Thread(task).start();
        try {
            // 获取线程返回值,主线程进入阻塞状态,直到子线程结束后得到返回值
            System.out.println(task.get());
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}



使用线程池管理线程


启动一个新线程的成本是比较高的,如果需要创建大量生命期很短的线程时,就使用线程池。
线程池在启动时即创建大量空闲的线程,程序将一个Runnable对象传给线程池,线程池就启动一条线程来执行该对象的 run() 方法,当 run() 方法执行结束后,该线程并不会死亡,而是再次返回线程池中成为空闲状态,等待下一个对象。


Executors类提供了5种线程池


newCachedThreadPool ()
创建一个具有缓存功能的线程池,若当前没有可用线程,就创建一个新的线程缓存到池中,若线程长时间(默认60秒)未被使用,则终止该线程。

newFixedThreadPool (int nThreads)
创建一个固定线程数的线程池,超出的线程会在队列中等待。

newSingleThreadExecutor ()
创建一个单线程的线程池,即线程顺序执行。

newScheduledThreadPool (int corePoolSize)
创建具有指定线程数的线程池,它可以在指定延迟后执行线程任务。

newSingleThreadScheduledExecutor ()
创建一个单线程的线程池,它可以在指定延迟后执行线程任务。

前三个方法返回 ExcutorService 对象,使用 submit() 或 execute() 方法提交线程任务
后两个方法返回 ScheduledExecutorService 对象,使用 schedule() 方法提交线程任务
线程任务可以是 Runnable 对象或 Callable 对象

// execute() 方法没有返回值,只能提交 Runnable 对象
Executors.newFixedThreadPool (6).execute (new Runnable () {
    public void run () {
        System.out. println (Thread.currentThread().getName () ) ;
    }
}) ;


// submit() 方法有返回值,提交 Runnable 对象时返回值为 null
Executors.newSingleThreadExecutor ().submit (new Runnable () {
    public void run () {
        System.out. println (Thread.currentThread().getName () ) ;
    }
}) ;


// submit() 方法可以返回 Callable 对象的返回值
Future<String> f=Executors.newCachedThreadPool ().submit (new Callable<String> () {
    public String call () {
        System.out. println (Thread.currentThread().getName () ) ;
        return "线程执行结束";
    }
}) ;


// schedule() 方法提交指定延迟的线程任务,可以作用在 Runnable 对象和 Callable 对象,Runnable 对象的返回值是 null
Executors.newScheduledThreadPool (6).schedule (new Runnable () {
    public void run () {
        System.out. println (Thread.currentThread().getName () ) ;
    }
//延迟3秒执行
}, 3, TimeUnit.SECONDS) ;



// scheduleAtFixedRate() 方法类似 schedule(),只是scheduleAtFixedRate() 方法可以设定线程重复执行的频率
Executors.newScheduledThreadPool (6).scheduleAtFixedRate (new Runnable () {
    public void run () {
        System.out. println (Thread.currentThread().getName () ) ;
    }
//延迟3秒执行,每2秒执行一次
}, 3, 2, TimeUnit.SECONDS) ;


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值