Java中线程的俩种方式,编码的变体

Java线程创建与优先级
本文介绍Java中创建线程的两种方法:继承Thread类和实现Runnable接口,并对比两者的区别,还介绍了如何设置线程优先级。

1.通过继承thread,得到一个任务类。

/*注意在构造器中启动这个线程的话,很容易造成this逃逸的问题,这是要注意的
* 这是通过直接集成thread来成为线程。同时在这种情况下,你可以通过调用合适的方法来
* thread对象赋予具体的名称。*/
public class SimpleThread extends  Thread {
    private int countDown=5;
    private static int threadCount=0;
    public SimpleThread() {
        super(Integer.toString(++threadCount));//这是给这个thread赋予名字。
        start();
    }

    public String toString(){
        return "#"+getName()+"("+countDown+"), ";
    }

    public void run() {
        while (true) {
            System.out.print(this);
            if (--countDown == 0) {
                return;
            }
        }
    }

    public static void main(String[] args) {
        for (int i = 0; i < 5; i++) {
            new SimpleThread();
        }
    }
}
运行的结果为:

#1(5), 
#2(5), 
#3(5), 
#3(4), 
#3(3), 
#3(2), 
#4(5), 
#2(4), 
#5(5), 
#5(4), 
#1(4), 
#5(3), 
#5(2), 
#2(3), 
#2(2), 
#2(1), 
#4(4), 
#4(3), 
#4(2), 
#4(1), 
#3(1), 
#5(1), 
#1(3), 
#1(2), 
#1(1), 

2.通过实现Runnable接口,来得到一个任务类。

//注意,Start()是在构造器中调用的。这个实例相当的简单,因此可能是安全的。但是应该注意到
//在构造器重启动线程可能会变得很有问题。因为另外一个任务可能会在构造器结束以前就开始执行了
//这意味着该任务能够访问处于不稳定状态的对象。这是优选Executor而不是显式地创建Thread对象的
//另外一个很重要的原因。
public class SelfManaged implements  Runnable {
    private int countDown=5;
    private Thread t = new Thread(this);

    public SelfManaged() {
        t.start();
    }

    public String toString(){
        return  Thread.currentThread().getName()+"("+countDown+")";
    }
    @Override
    public void run() {
        while (true) {
            System.out.println(this);
            if (--countDown == 0) {
                return;
            }
        }

    }

    public static void main(String[] args) {
        for (int i = 0; i < 5; i++) {
            new SelfManaged();
        }

    }
}
最后运行的结果为:
Thread-0(5)
Thread-2(5)
Thread-1(5)
Thread-1(4)
Thread-2(4)
Thread-2(3)
Thread-2(2)
Thread-2(1)
Thread-0(4)
Thread-0(3)
Thread-0(2)
Thread-0(1)
Thread-3(5)
Thread-1(3)
Thread-3(4)
Thread-4(5)
Thread-4(4)
Thread-4(3)
Thread-4(2)
Thread-4(1)
Thread-1(2)
Thread-1(1)
Thread-3(3)
Thread-3(2)
Thread-3(1)

3.为线程设置优先级。但是设置优先级只是一个建议。具体是否执行的话,还是要看系统内部的调度。

public class SimplePriorities implements  Runnable {
    private int countDown=5;
    private volatile  double d;
    private int priority;

    public SimplePriorities(int priority) {
        this.priority=priority;
    }

    public String toString(){
        return Thread.currentThread()+":"+countDown;
    }
    @Override
    public void run() {
        Thread.currentThread().setPriority(priority);//为这个线程设置优先级。
        while (true) {
            for (int i = 0; i < 10000; i++) {
                d += (Math.PI + Math.E)/(double)i;
                if (i / 1000 == 0) {
                    Thread.yield();
                }
            }
            System.out.println(this);
            if (--countDown == 0) {
                return;
            }
        }
    }

    public static void main(String[] args) {
        ExecutorService exec= Executors.newCachedThreadPool();
        for (int i = 0; i < 5; i++) {
            exec.execute(new SimplePriorities(Thread.MAX_PRIORITY));
            exec.execute(new SimplePriorities(Thread.MIN_PRIORITY));
            exec.shutdown();
        }
    }
}
4继承thread和实现runnable之间的区别:

1.如是是实现了Runnable接口的话,那么就为实现多继承提供了方便。因为java中,只允许单继承。

2.实现runnable接口可以实现资源的共享。

这就是它们之间的最大的区别。

下面以一个买票的例子来说明它们之间的区别。

  1. class MyThread extends Thread{  
  2. private int ticket=10;  
  3. public void run(){  
  4. for(int i=0;i<20;i++){  
  5. if(this.ticket>0){  
  6. System.out.println("卖票:ticket"+this.ticket--);  
  7. }  
  8. }  
  9. }  
  10. }; 

下面通过三个线程对象,同时卖票:

  1. package org.demo.dff;  
  2. public class ThreadTicket {  
  3. public static void main(String[] args) {  
  4. MyThread mt1=new MyThread();  
  5. MyThread mt2=new MyThread();  
  6. MyThread mt3=new MyThread();  
  7. mt1.start();//每个线程都各卖了10张,共卖了30张票  
  8. mt2.start();//但实际只有10张票,每个线程都卖自己的票  
  9. mt3.start();//没有达到资源共享  
  10. }  
  1. package org.demo.runnable;  
  2. class MyThread implements Runnable{  
  3. private int ticket=10;  
  4. public void run(){  
  5. for(int i=0;i<20;i++){  
  6. if(this.ticket>0){  
  7. System.out.println("卖票:ticket"+this.ticket--);  
  8. }  
  9. }  
  10. }  
  11. }  
  12. package org.demo.runnable;  
  13. public class RunnableTicket {  
  14. public static void main(String[] args) {  
  15. MyThread mt=new MyThread();  
  16. new Thread(mt).start();//同一个mt,但是在Thread中就不可以,如果用同一  
  17. new Thread(mt).start();//个实例化对象mt,就会出现异常  
  18. new Thread(mt).start();  
  19. }  
  20. }; 
但是这个程序是有问题的。可能会涉及到锁的问题。可以使用Synchronized来进行锁定。这是要注意的。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

爱coding的同学

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值