目录
线程
线程和进程是密不可分的,一个进程独占一个CPU资源,而多个线程对CPU资源进行共享,一个进程可以有多个线程,但进程与进程之间相互独立。
还有一个协程
多线程有三种方法可以实现:Thread、Runnable、Callable。
Thread:
线程子类继承(extends)Thread,在类中覆写run(),main内进行实例化后调用start(),开启线程。class MyThread extends Thread{
public String name;
public MyThread(String name){
this.name = name;
}
@Override
public void run() {
for(int i=0;i<50;i++){
System.out.println(this.name+"-->"+i);
}
}
}
public class Demo01 {
public static void main(String[] args) { //使用继承extendsThread来实现多线程
MyThread myThreadA = new MyThread("线程A");
MyThread myThreadB = new MyThread("线程B");
MyThread myThreadC = new MyThread("线程C");
myThreadA.start();
myThreadB.start();
myThreadC.start();
}
}
在Thread中有一个 start0() , start() 调用JVM的函数 start0(),而start0()去操作系统内匹配底层函数,来启动线程。
Runnable:
- 线程子类实现(implements)Runnable接口,覆写run(),但Runnable内没有start()来启动线程,必须使用 new Thread(Runnable子类实例).start() 来启动线程。
class MyRunnable implements Runnable{
private String name;
public MyRunnable(String name){
this.name = name;
}
@Override
public void run() {
for(int i=0;i<50;i++){
System.out.println(this.name+"-->"+i);
}
}
}
public class Demo01 { //使用implements实现Runnable来实现多线程
public static void main(String[] args) {
MyRunnable runnableA = new MyRunnable("RunnableA");
MyRunnable runnableB = new MyRunnable("RunnableB");
MyRunnable runnableC = new MyRunnable("RunnableC");
new Thread(runnableA).start();
new Thread(runnableB).start();
new Thread(runnableC).start();
}
}
- Runnable是函数接口自然可以使用Lamdba(简单、代码少)。
public class Demo02 { //Lambda表达式实现多线程
public static void main(String[] args) {
String names[] = new String[]{"线程A","线程B","线程C"};
for (String name:names){
new Thread(() ->{
for(int i=0;i<50;i++){
System.out.println(name+"-->"+i);
}
}).start();
}
}
}
Runnable实现线程启动要使用new Thread(子类实例).start(),但其实就是传入子类实例通过子类实例调用run()。
public void run() {
if (this.target != null) { //target为子类实例
this.target.run();
}
}
Runnable和Thread:
Runnable实现多线程要比Thread好,Thread只能单继承,Runnable可以实现多个接口,还可以使用Lamdba简化代码,可以更加方便描述出资源共享(多个线程共享同一个资源),**多线程的实现主要靠Runnable定义核心业务处理功能,描述则通过Thread类定义。**简单的线程资源共享:
class TicketThread implements Runnable {
private int ticket = 25;
@Override
public void run() {
while(ticket >0){
System.out.println("卖票:"+ticket--);
}
}
}
public class Demo03 {
public static void main(String[] args) {
TicketThread ticket = new TicketThread();
new Thread(ticket).start(); //多个线程共享资源
new Thread(ticket).start(); //多个线程共享资源
new Thread(ticket).start(); //多个线程共享资源
}
}
Callable:
解决了Thread和Runnable的run()方法没有返回值的缺陷,但比Thread和Runnable更加复杂。
Callable实现多线程:
class MyCallable<V> implements Callable<V>{
private V name;
public MyCallable(V name){
this.name = name;
}
@Override
public V call() throws Exception {
for(int i=0;i<50;i++){
System.out.println(this.name+":"+i);
}
return (V)"执行结束!!!";
}
}
public class Demo01 {
public static void main(String[] args) {
Callable<String> callA = new MyCallable<String>("线程A");
Callable<String> callB = new MyCallable<String>("线程B");
Callable<String> callC = new MyCallable<String>("线程C");
FutureTask<String> futureA = new FutureTask<String>(callA);
FutureTask<String> futureB = new FutureTask<String>(callB);
FutureTask<String> futureC = new FutureTask<String>(callC);
new Thread(futureA).start();
new Thread(futureB).start();
new Thread(futureC).start();
try{
System.out.println(futureA.get());
System.out.println(futureB.get());
System.out.println(futureC.get());
}catch (InterruptedException e){
e.printStackTrace();
}catch (ExecutionException e){
e.printStackTrace();
}
}
}