java实现多线程抢单_Java实现多线程的方式

多线程主要有两种实现方法,分别是继承Thread类与实现Runnable接口。

继承Thread类以后无法再继承其他类,但实现Runnable接口的方式解决了Java单继承的局限;此外,Runnable接口实现多线程可以实现数据共享(传递给Thread的参数均为实现Runnable接口的类的同一个对象)。

启动一个线程是调用start()方法,它将启动一个新线程,使线程就绪状态,以后可以被调度为运行状态,同时在其中调用了native的方法(与操作系统有关);一个线程必须关联一些具体的执行代码,

run()方法是该线程所关联的执行代码。

一、继承Thread类

重写Thread类的run方法即可,那么当线程启动的时候,就会执行run方法体的内容。代码如下:

public class ThreadDemo extendsThread {

@Overridepublic voidrun() {while (true) {

System.out.println(Thread.currentThread().getName()+ " is running ... "); //打印当前线程的名字

try{

Thread.sleep(1000); //休息1000ms

} catch(InterruptedException e) {

e.printStackTrace();

}

}

}public static voidmain(String[] args) {

ThreadDemo td= newThreadDemo();

td.start();//启动线程

while (true) {

System.out.println(Thread.currentThread().getName()+ " is running ... "); //打印当前线程的名字

try{

Thread.sleep(1000); //休息1000ms

} catch(InterruptedException e) {

e.printStackTrace();

}

}

}

}

运行结果如下:

main is running ...

Thread-0is running ...

main is running ...

Thread-0is running ...

Thread-0is running ...

main is running ...

Thread-0is running ...

main is running ...

我们发现这里有个问题,多个线程的名字都是系统定义好的,就是Thread-开头,后面跟数字,如果我们每个线程处理不同的任务,那么我们能不能给线程起上不同的名字,方便我们排查问题呢?答案是可以的。只要在创建线程实例的时候,在构造方法中传入指定的线程名称即可。如:

publicThreadDemo(String name) {super(name);

}

二、实现Runnable接口

实现Runnable接口也是一种常见的创建线程的方式。使用接口的方式可以让我们的程序降低耦合度。

Runnable接口中仅仅定义了一个方法,就是run。我们来看一下Runnable接口的代码。

packagejava.lang;

@FunctionalInterfacepublic interfaceRunnable {public abstract voidrun();

}

其实Runnable就是一个线程任务,线程任务和线程的控制分离,这也就是上面所说的解耦。

1、线程任务类

public class ThreadTarget implementsRunnable {

@Overridepublic voidrun() {while(true) {

System.out.println(Thread.currentThread().getName()+ " is running .. ");try{

Thread.sleep(500);

}catch(InterruptedException e) {

e.printStackTrace();

}

}

}

}

2、可运行的线程类

public classMain {public static voidmain(String[] args) {

ThreadTarget tt= new ThreadTarget(); //实例化线程任务类

Thread t = new Thread(tt); //创建线程对象,并将线程任务类作为构造方法参数传入

t.start(); //启动线程//主线程的任务,为了演示多个线程一起执行

while(true) {

System.out.println(Thread.currentThread().getName()+ " is running .. ");try{

Thread.sleep(500);

}catch(InterruptedException e) {

e.printStackTrace();

}

}

}

}

三、使用内部类的方式(另一种写法)

public classDemoThread {public static voidmain(String[] args) {//基于子类的实现

newThread() {public voidrun() {while (true) {

System.out.println(Thread.currentThread().getName()+ " is running ... "); //打印当前线程的名字

try{

Thread.sleep(1000); //休息1000ms

} catch(InterruptedException e) {

e.printStackTrace();

}

}

};

}.start();//基于接口的实现

new Thread(newRunnable() {

@Overridepublic voidrun() {while (true) {

System.out.println(Thread.currentThread().getName()+ " is running ... "); //打印当前线程的名字

try{

Thread.sleep(1000); //休息1000ms

} catch(InterruptedException e) {

e.printStackTrace();

}

}

}

}).start();//主线程的方法

while (true) {

System.out.println(Thread.currentThread().getName()+ " is running ... "); //打印当前线程的名字

try{

Thread.sleep(1000); //休息1000ms

} catch(InterruptedException e) {

e.printStackTrace();

}

}

}

}

四、定时器

例1:在2017年10月11日晚上10点执行任务。

importjava.text.SimpleDateFormat;importjava.util.Timer;importjava.util.TimerTask;/*** 定时器举例

**/

public classTimerDemo {private static final SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd hh:mm:ss");public static void main(String[] args) throwsException {

Timer timer= newTimer();

timer.schedule(newTimerTask() {

@Overridepublic voidrun() {

System.out.println("定时任务执行了....");

}

}, format.parse("2017-10-11 22:00:00"));

}

}

例2: 每隔5s执行一次

importjava.util.Date;importjava.util.Timer;importjava.util.TimerTask;public classTimerDemo2 {public static voidmain(String[] args) {

Timer timer= newTimer();

timer.schedule(newTimerTask() {

@Overridepublic voidrun() {

System.out.println("Hello");

}

},new Date(), 5000);

}

}

五、带返回值的线程实现方式

1. 创建一个类实现Callable接口,实现call方法。这个接口类似于Runnable接口,但比Runnable接口更加强大,增加了异常和返回值。

public interface Callable{

V call()throwsException;

}

2. 创建一个FutureTask,指定Callable对象,作为线程任务。

3. 创建线程,指定线程任务FutureTask。

4. 启动线程。

importjava.util.concurrent.Callable;importjava.util.concurrent.ExecutionException;importjava.util.concurrent.Future;importjava.util.concurrent.FutureTask;public classCallableTest {public static void main(String[] args) throwsException {

Callable call = new Callable() {

@Overridepublic Integer call() throwsException {

System.out.println("thread start .. ");

Thread.sleep(2000);return 1;//可以返回一个Integer值

}

};

FutureTask task = new FutureTask<>(call);

Thread t= newThread(task);

t.start();

System.out.println("do other thing .. ");

System.out.println("拿到线程的执行结果 : " +task.get()); //可以通过FutureTask的get()方法获得返回值,注意:get方法是阻塞的,线程无返回结果,get方法会一直等待。

}

}

运行结果如下:

doother thing ..

thread start ..

拿到线程的执行结果 :1

六、基于线程池的方式

那么每次需要的时候创建,不需要的时候销毁,是非常浪费资源的。那么我们就可以使用缓存的策略,也就是使用线程池。

importjava.util.concurrent.ExecutorService;importjava.util.concurrent.Executors;public classThreadPoolDemo {public static voidmain(String[] args) {//创建线程池

ExecutorService threadPool = Executors.newFixedThreadPool(10);while(true) {

threadPool.execute(new Runnable() { //提交多个线程任务,并执行

@Overridepublic voidrun() {

System.out.println(Thread.currentThread().getName()+ " is running ..");try{

Thread.sleep(3000);

}catch(InterruptedException e) {

e.printStackTrace();

}

}

});

}

}

}

运行结果如下:

pool-1-thread-4is running ..

pool-1-thread-1is running ..

pool-1-thread-6is running ..

pool-1-thread-2is running ..

pool-1-thread-8is running ..

pool-1-thread-3is running ..

pool-1-thread-5is running ..

pool-1-thread-9is running ..

pool-1-thread-10is running ..

pool-1-thread-7 is running ..

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值