多线程

天下之事常成于困约,而败于奢靡。这篇文章主要讲述多线程相关的知识,希望能为你提供帮助。
线程创建implements Runnable
实现Runnable接口,重写run()方法,通过Thread(Runnable target) 构造方法创建Thread,调用start开启线钱程;

public class RunableImpl implements Runnable
@Override
public void run()
for (int i = 0; i < 1000; i++)
System.out.println("测试线程"+i);


public static void main(String[] args)
Thread thread = new Thread(new RunableImpl());
thread.start(); //start()开启线程
for (int i = 0; i < 1000; i++)
System.out.println("main主线程"+i);



extends Thread
继承Thread类,重写run()方法,调用start开启线钱程;
注意:线程开启不一定立即执行,由CPU 调度执行。
不建议使用,避免OOP单继承局限性。
其实 Thread 类实现了Runnable接口:public class Thread implements Runnable
public class TestThread extends Thread
@Override
public void run()
for (int i = 0; i < 1000; i++)
System.out.println("测试线程"+i);


public static void main(String[] args)
TestThread testThread = new TestThread();
testThread.start(); //start()开启线程
for (int i = 0; i < 1000; i++)
System.out.println("main主线程"+i);



静态代理模式总结:真实对象和代理对象都需要实现同一个接口,代理对象代理的真实对象。
好处:代理对象可以做很多真实对象做不了的事情,真实对象专注做自己的事情。
public class StaticProxy
public static void main(String[] args)
//阿里规范:不要显式创建线程,请使用线程池。
new Thread(()-> System.out.println("我也是静态代理")).start();
new ProxyObject(new RealObject()).Happy();


interface Marry
void Happy();

class RealObject implements Marry
@Override
public void Happy()
System.out.println("真实对象:我结婚");


//代理对象
class ProxyObject implements Marry
private Marry target;
publicProxyObject(Marry marry)
this.target=marry;

@Override
public void Happy()
System.out.println("代理前我能做:办酒席");
this.target.Happy();
System.out.println("代理后我能做:生孩子");


implements Callable< V> ?
Runnable和Callable的区别?- Runnable执行方法是run(),Callable是call()
- 实现Runnable接口的任务线程无返回值;实现Callable接口的任务线程能自定义返回值< V>
-call方法可以抛出异常,run方法若有异常只能在内部消化
public class TestCallable implements Callable< Boolean>
/**
call()返回值:V> – the result type
*/
@Override
public Boolean call() throws Exception
return true;


public static void main(String[] args) throws ExecutionException, InterruptedException
TestCallable ca = new TestCallable();
ExecutorService exe = Executors.newFixedThreadPool(3);
Future< Boolean> future = exe.submit(ca);
System.out.println(future.get());
exe.shutdownNow();


阿里规约:线程池不允许使用Executors去创建,而是通过ThreadPooExecutor的方式,这样的处理方式让写的同学更加明确线程池的运行规则,规避资源耗尽的风险。
线程池Executors创建的几种线程池?
> newCachedThreadPool创建一个可缓存线程池,如果线程池长度超过处理需要,可灵活回收空闲线程,若无可回收,则新建线程。
> newFixedThreadPool 创建一个定长线程池,可控制线程最大并发数,超出的线程会在队列中等待。
> newScheduledThreadPool 创建一个定长线程池,支持定时及周期性任务执行。
> newSingleThreadExecutor 创建一个单线程化的线程池执行任务。
ThreadPoolExecutor的参数?
--- > class AbstractExecutorService implements ExecutorService
--- > classThreadPoolExecutor extends AbstractExecutorService
public ThreadPoolExecutor(int corePoolSize, int maximumPoolSize,long keepAliveTime, TimeUnit unit,BlockingQueue< Runnable> workQueue)
this(corePoolSize, maximumPoolSize, keepAliveTime, unit, workQueue,Executors.defaultThreadFactory(), defaultHandler);
> corePoolSize:线程池中所保存的核心线程数,包括空闲线程。
> maximumPoolSize:池中允许的最大线程数。
> keepAliveTime:线程池中的空闲线程所能持续的最长时间。
> unit:持续时间的单位。
> workQueue:任务执行前保存任务的队列,仅保存由execute方法提交的Runnable任务。
FutureTask一个可取消的异步计算。FutureTask提供了对Future的基本实现,可以调用方法去开始和取消一个计算,可以查询计算是否完成并且获取计算结果。只有当计算完成时才能获取到计算结果,一旦计算完成,计算将不能被重启或者被取消,除非调用runAndReset方法。
除了实现了Future接口以外,FutureTask还实现了Runnable接口,因此FutureTask交由Executor执行,也可以直接用线程调用执行(futureTask.run())。
一个FutureTask可以用来包装一个Callable或Runnable对象。
//将任务放进FutureTask里
FutureTask< Object> futureTask = new FutureTask< > (实现了Callable的类实例);
Thread thread = new Thread(futureTask);
thread.start();
//或:
ExecutorService executorService=Executors.newCachedThreadPool();
executorService.submit(futureTask);
executorService.shutdown();

线程状态


线程同步synchronized 关键字
synchronized 方法:锁的对象是this;
【多线程】synchronized(Object )块:可以传入一个任意对象,锁的是那个对象。
public class TestBuyTicket
public static void main(String[] args)
BuyTicket buyTicket = new BuyTicket();
new Thread(buyTicket,"线程1").start();
new Thread(buyTicket,"线程2").start();
new Thread(buyTicket,"线程3").start();


class BuyTicket implements Runnable
private int num =10;

    推荐阅读