Java 实现线程的四种方式

1.实现Runnable接口

//Implement the interface Runnable, while the Runnable only have one abstract run() method, So all the thread that implement Runnable cant return the run() method result and also cant throw the pre defined exception
// Test Class
public class Ticket {
    Lock reentrantLocaLock = new ReentrantLock();
    
    static int total;
    static {
        total = 50;
    }
    
    private static Ticket ticket;
    public synchronized static Ticket getInstance() {
        if(ticket ==null) {
            ticket = new Ticket();
        }
        return ticket;
    }

    public void sellTicket() {
        while (true) {
            reentrantLocaLock.lock();
            try {
                if (Ticket.total > 0) {
                    Ticket.total--;
                    System.out.println(Thread.currentThread().getName() + " sold one ticket, and tickets remain "
                            + Ticket.total);
                } else {
                    System.out.println(Thread.currentThread().getName() + " Sorry, tickets sold out,tickets remain "
                            + Ticket.total);
                    break;
                }
            } catch (Exception e) {
                e.printStackTrace();
            } finally {
                reentrantLocaLock.unlock();
                // to fast for the cpu, we need to manually switch thread
                try {
                    Thread.sleep(1000);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        }
    }
}

//Thread 
public class MyThreadImpl implements Runnable {
    
    @Override
    public void run() {
        Ticket ticket = Ticket.getInstance();
        ticket.sellTicket();
    }
}



------

public class ThreadTest {

    public static void main(String[] args) {

        MyThreadImpl threadImpl =new MyThreadImpl();
        for(int i=1;i<4;i++){
            new Thread(threadImpl,"Thread-R"+i).start();
        }
     }
}

         1.实现Runnbale接口创建线程更加符合面向对象的特点,在实际情况中多使用这种方式创建线程

        2.此种方式实现线程,在线程执行结束后不会有返回值

2.继承自Thread类

// Class Ticket refer to the Impl module code 
public class MyThreadExt extends Thread{
    //Because the class Thread also impl the inteface Runnable, So there is not big diff between Impl
    @Override
    public void run() {
        Ticket ticket = Ticket.getInstance();
        ticket.sellTicket();
    }
}

---------
//Thread test
public class ThreadTest {

    public static void main(String[] args) {

        MyThreadExt threadExt =new MyThreadExt();
        for(int i=1;i<4;i++){
             new Thread(threadExt,"Thread-E"+i).start();
        }
   }

}

        1. 通过继承Thread类来实现线程的方式虽然可用,但却不太符合面向对象的特点,一般不使用此方式实现线程

        2. 此种方式实现线程,在线程执行结束后不会有返回值

3.实现Callable接口

//The the diff between inteface Callable and Runnable are Callable can return the result when a thread end of run, And also can return the pre defined Exceprion

// Class Ticket refer to the Impl module code
public class MyThreadCallable implements Callable<Object> {
    
    @Override
    public Object call() throws Exception {
        Ticket ticket = Ticket.getInstance();
        ticket.sellTicket();
        return null;
    }
}

-----
//Thread test
public class ThreadTest {
    public static void main(String[] args) {
        
        Callable callable=new MyThreadCallable();
        FutureTask ftask=new FutureTask(callable);

        for(int i=0;i<4;i++){
            new Thread(ftask,"Thread-C"+i).start();
        }
    }
}

        1. 实现Callable接口创建线程与实现Runnable接口类似,都符合面向对象特点

        2. 实现Callable接口创建线程允许在线程执行结束后存在返回值

4.使用线程池

-------------
//Thread test
public class ThreadTest {
    public static void main(String[] args) {
        
        Callable callable=new MyThreadCallable();
        MyThreadImpl threadImpl =new MyThreadImpl();
        
        ExecutorService newFixedThreadPool = Executors.newFixedThreadPool(3);
        ExecutorService newCachedThreadPool = Executors.newCachedThreadPool();
        ExecutorService newSingleThreadExecutor = Executors.newSingleThreadExecutor();
        ExecutorService newScheduledThreadPool = Executors.newScheduledThreadPool(3);
        ExecutorService newWorkStealingPool = Executors.newWorkStealingPool();
        
        // exec thread without return
        newFixedThreadPool.execute(threadImpl);

        // exec thread have return
        newFixedThreadPool.submit(threadImpl);
        

        //close the thread pool
        newFixedThreadPool.shutdown();
    }
}

        1. 使用线程池可以在各种场景下更加合理的运用多线程

        2. execute() 针对的是没有不需要返回结果的线程执行,submit() 作用于有返回结果的线程执行

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值