初见JAVA多线程—三种启动/与调度
Tread、Runnable、Callable的几种启动方式示例:
Thread启动多线程
1、定义Thread类的子类,并重写该类的run()方法,该run()方法的方法体就代表了线程需要完成的任务。因此把run方法称为线程执行体。
2、创建Thread子类的实例,即创建了线程对象。
3、调用线程对象的start()方法来启动该线程。
class MyThread extends Thread{
private String name;
MyThread(String name){
this.name=name;
}
@Override
public void run() {
for(int i=0;i<10;i++)
System.out.println("线程执行"+name+i);
}
}
public class test {
public static void main(String[] args){
new MyThread("A").start();
new MyThread("B").start();
new MyThread("C").start();
}
}
Runnable启动多线程:
实现Runnable接口创建并启动多线程的步骤如下:
1.定义Runnable接口的实现类,并重写该接口的run方法,该run方法的方法体同样是该线程的线程执行体
2.创建Runnable实现类的实例对象,并以此实例对象作为Thread的target来创建Thread类,该Thread对象才是真正的线程对象。
3.调用线程对象的start()方法来启动该线程。
class MyThread implements Runnable{
private String name;
MyThread(String name){
this.name=name;
}
@Override
public void run() {
for(int i=0;i<10;i++)
System.out.println("线程执行"+name+i);
}
}
public class test {
public static void main(String[] args){
new Thread(new MyThread("A")).start();
new Thread(new MyThread("B")).start();
new Thread(new MyThread("C")).start();
}
}
一般使用lamba表达式/匿名内部类:
new Thread(()->{
for(int i=0;i<10;i++)
System.out.println("线程执行"+name+i);
})
new Thread(new Runnable() {
public void run() {
for (int i = 0; i < 50; i++) {
System.out.println(Thread.currentThread().getName() + "执行" + i);
}
}
}).start();
Callable启动多线程:
Callable和Runnable使用差不多, 但是Callable有返回值, 可以用Future接收. 看代码: (Callable来重写call()方法,用以实现业务逻辑,拥有返回值。Callable对象由FutureTask对象接受,FutureTask对象具有get()对象以得到返回值)
import java.util.concurrent.Callable;
import java.util.concurrent.FutureTask;
class mythread implements Callable<String>{
private String name;
mythread(String name){
this.name=name;
}
@Override
public String call() throws Exception {
for(int i=0;i<10;i++)
System.out.println("线程执行"+name+i);
return name+"执行结束";
}
}
public class Demo {
public static void main(String args[])throws Exception{
FutureTask<String> my=new FutureTask<>(new mythread("A"));
FutureTask<String> my1=new FutureTask<>(new mythread("b"));
FutureTask<String> my2=new FutureTask<>(new mythread("C"));
new Thread(my).start();
new Thread(my1).start();
new Thread(my2).start();
System.out.println(my.get());
System.out.println(my1.get());
System.out.println(my2.get());
线程的调度
调度策略:
时间片:线程的调度采用时间片轮转的方式
抢占式:高优先级的线程抢占CPU
Java的调度方法:
1.对于同优先级的线程组成先进先出队列(先到先服务),使用时间片策略
2.对高优先级,使用优先调度的抢占式策略
线程的优先级
等级:
MAX_PRIORITY:10
MIN_PRIORITY:1
NORM_PRIORITY:5
方法:
getPriority():返回线程优先级
setPriority(int newPriority):改变线程的优先级
注意!:高优先级的线程要抢占低优先级的线程的cpu的执行权。但是仅是从概率上来说的,高优先级的线程更有可能被执行。并不意味着只有高优先级的线程执行完以后,低优先级的线程才执行。