1、什么是线程?java
线程:程序中一个单一的顺序控制流程。进程内一个相对独立的、可调度的执行单元,是系统独立调度和分派CPU的基本单位。编程
多线程:单个程序中同时运行多个线程完成不一样的工做,称为多线程。微信
特色:多线程
1)轻量级的进程,程序运行流中可执行的最小单元,线程不拥有系统资源,多个线程共享进程拥有的资源。并发
2)一个线程能够建立另一个线程,多个线程能够并发执行。ide
3)多个线程在系统运行中抢占资源,会出现间断性,咱们看到的是并行执行,其实在有前后顺序的。spa
4)一个进程至少包含一个线程,即主线程。线程
2、线程有哪些状态?对象
线程具备:新建,就绪,运行,阻塞,终止五种状态。继承
①新建:线程被建立,没有执行任何方法,如,Thread th = new Thread()。
②就绪:当调用线程的start方法时,就会触发线程状态变动为就绪态,等待cpu来调用。处于就绪态的线程才会被cpu调度,单cpu不是当即执行它。
③运行:当cpu发起对此线程调用时,它就进入了运行态。
④阻塞:当线程因为某种缘由,再也不拥有cpu使用权,它就会被阻塞。
阻塞有如下几种状况:
1)sleep(long mills):参数为毫秒数,使线程在指定的时间内进入阻塞,时间一过,进入就绪态。
2)suspend() 和 resume():suspend会让线程挂起,必须执行resume进行线程的恢复。
3)yield():与sleep()相似,可是不能由用户指定暂停多长时间,只能出让机会给同优先级的线程,且不进入阻塞。如同排队,前面的人和后面的人交换位置,可是还处在队伍中。
4)wait() 和 notify():wait() 使线程进入阻塞状态,有两种形式,一种指定毫秒数,另外一种无参。前者可经过notify()唤起或者超过指定时间自动恢复;后者必须经过notify()唤起。
5)同步阻塞:等待同步锁资源。多线程竞争同一个资源时,只能一个线程得到锁,其它的线程要等待。
⑤终止:线程执行完毕,或者出现异常,线程结束。
3、如何建立线程?
java线程的实现方式有三种:继承Thread类、实现Runnable接口,使用Callable和FutureTask(能够有返回值)
一、经过集成Thread类,覆写run()方法
class MyThread extends Thread {
@Override
public void run() {
for (int i = 0; i < 10; i++) {
System.out.println(Thread.currentThread().getName() + " " + i);
}
}
}
public class ThreadDemo {
public static void main(String[] args) {
System.out.println(Thread.currentThread().getName());
MyThread th1 = new MyThread();
MyThread th2 = new MyThread();
th1.start();
th2.start();
}
}
输出:main
Thread-1 0
Thread-0 0
Thread-1 1
Thread-1 2
......
线程要实现的逻辑写在run方法中,经过执行线程的start()方法,使线程进入就绪状态,等待CPU分配资源。
能够看到两个线程并行执行,且随机得到CPU。
二、试过实现Runnable接口,实现run()方法
class MyThread implements Runnable {
@Override
public void run() {
for (int i = 0; i < 10; i++) {
System.out.println(Thread.currentThread().getName() + " " + i);
}
}
}
public class ThreadDemo {
public static void main(String[] args) {
System.out.println(Thread.currentThread().getName());
MyThread th = new MyThread();
Thread t1 = new Thread(th);
Thread t2 = new Thread(th);
t1.start();
t2.start();
}
}
输出:main
Thread-0 0
Thread-0 1
Thread-1 0
Thread-0 2
......
经过将MyThread实例传入Thread构造方法实例化Thread,调用Thread的start方法,启动线程。
ps:继承Thread和实现Runnable接口有什么区别呢?
1:前者为单继承,有局限性,但接口的方式能够实现多个。
2:后者能够实现资源共享。
多线程编程中,强烈建议使用Runnable
三、使用Callable和Future接口建立线程。
具体是建立Callable接口的实现类,并实现clall()方法。
并使用FutureTask类来包装Callable实现类的对象,且以此FutureTask对象做为Thread对象的target来建立线程。
class MyCallable implements Callable<Integer> {
@Override
public Integer call() throws Exception {
return 1;
}
}
public class ThreadDemo {
public static void main(String[] args) {
Callable<Integer> myCallable = new MyCallable();//实例化MyCallable
FutureTask<Integer> ft = new FutureTask<>(myCallable);//通FutureTask包装
Thread thread = new Thread(ft);//将FutureTask传入Thread构造,实例化线程
thread.start();//线程启动
Integer result = ft.get();//获取返回值
System.out.println(result);
}
}
1)实现Callable接口中的call()方法,这个是线程要执行的逻辑。
2)FutureTask的get()方法会一直阻塞,直到call()方法执行完毕取到返回值。
关注老姜谈技术,微信号:helojava,或者扫描下面二维码。
每日一帖,技术鸡汤。