文章目录
- 1、创建一个类实现Runnable接口,并重写run方法。
- 2、创建一个类继承Thread类,并重写run方法。
- 3、实现Callable接口,重写call()方法,这种方式可以通过FutureTask获取任务执行的返回值。
- 4、run()方法和start()方法有什么区别?
- 5、通过继承 Thread 的方法和实现 Runnable 接口的方式创建多线程,哪个好?
- 6、两种常见的线程控制方法
1、创建一个类实现Runnable接口,并重写run方法。
public class MyThread implements Runnable{
ArrayList<String>aaa;
public MyThread(ArrayList<String>aaa){
this.aaa=aaa;
}
@Override
public void run() {
for (int i=0;i<100;i++){
aaa.add("aaa"+i);
System.out.println(Thread.currentThread().getName()+"aaa"+i+aaa.get(i));
}
}
}
写一个测试方法
public class ListDemo {
public static void main(String[] args) {
ArrayList<String>list=new ArrayList<>();
MyThread m1=new MyThread(list);
MyThread m2=new MyThread(list);
new Thread(m1).start();
new Thread(m2).start();
}
}
-----结果------
Thread-0aaa0aaa0
Thread-1aaa0aaa0
Thread-0aaa1aaa0
Thread-1aaa1aaa0
Thread-0aaa2aaa1
Thread-1aaa2aaa1
Thread-0aaa3aaa1
Thread-1aaa3aaa1
Thread-0aaa4aaa2
Thread-1aaa4aaa2
Thread-0aaa5aaa2
Thread-1aaa5aaa2
Thread-1aaa6aaa3
Thread-1aaa7aaa3
Thread-0aaa6aaa3
Thread-1aaa8aaa4
Thread-1aaa9aaa4
Thread-0aaa7aaa3
Thread-1aaa10aaa5
Thread-0aaa8aaa4
Thread-1aaa11aaa5
Thread-0aaa9aaa4
Thread-1aaa12aaa6
Thread-1aaa13aaa6
Thread-0aaa10aaa5
Thread-1aaa14aaa7
Thread-0aaa11aaa5
Thread-1aaa15aaa8
Thread-0aaa12aaa6
Thread-1aaa16aaa7
Thread-0aaa13aaa6
Thread-1aaa17aaa9
Thread-0aaa14aaa7
Thread-1aaa18aaa10
Thread-0aaa15aaa8
Thread-1aaa19aaa8
Thread-0aaa16aaa7
Thread-0aaa17aaa9
Thread-0aaa18aaa10
Thread-0aaa19aaa8
Process finished with exit code 0
2、创建一个类继承Thread类,并重写run方法。
public class MyThread extends Thread{
ArrayList<String>aaa;
public MyThread(ArrayList<String>aaa){
this.aaa=aaa;
}
@Override
public void run() {
for (int i=0;i<20;i++){
aaa.add("aaa"+i);
System.out.println(Thread.currentThread().getName()+"aaa"+i+aaa.get(i));
}
}
}
------结果------
Thread-0aaa0null
Thread-1aaa0null
Thread-0aaa1aaa0
Thread-1aaa1aaa0
Thread-0aaa2aaa1
Thread-1aaa2aaa1
Thread-0aaa3aaa1
Thread-1aaa3aaa1
Thread-0aaa4aaa2
Thread-1aaa4aaa2
Thread-0aaa5aaa2
Thread-1aaa5aaa2
Thread-0aaa6aaa3
Thread-1aaa6aaa3
Thread-0aaa7aaa3
Thread-1aaa7aaa3
Thread-0aaa8aaa4
Thread-1aaa8aaa4
Thread-0aaa9aaa4
Thread-0aaa10aaa5
Thread-1aaa9aaa4
Thread-0aaa11aaa5
Thread-1aaa10aaa5
Thread-0aaa12aaa6
Thread-0aaa13aaa6
Thread-0aaa14aaa7
Thread-1aaa11aaa5
Thread-0aaa15aaa7
Thread-1aaa12aaa6
Thread-0aaa16aaa8
Thread-1aaa13aaa6
Thread-0aaa17aaa8
Thread-1aaa14aaa7
Thread-0aaa18aaa9
Thread-1aaa15aaa7
Thread-0aaa19aaa10
Thread-1aaa16aaa8
Thread-1aaa17aaa8
Thread-1aaa18aaa9
Thread-1aaa19aaa10
Process finished with exit code 0
3、实现Callable接口,重写call()方法,这种方式可以通过FutureTask获取任务执行的返回值。
public class CallerTask implements Callable<String> {
public String call() throws Exception {
return "Hello,i am running!";
}
public static void main(String[] args) {
//创建异步任务
FutureTask<String> task=new FutureTask<String>(new CallerTask());
//启动线程
new Thread(task).start();
try {
//等待执行完成,并获取返回结果
String result=task.get();
System.out.println(result);
} catch (InterruptedException e) {
e.printStackTrace();
} catch (ExecutionException e) {
e.printStackTrace();
}
}
}
-----结果-----
Hello,i am running!
4、run()方法和start()方法有什么区别?
run():封装线程执行的代码,直接调用相当于调用普通方法。
start():启动线程,然后由JVM 调用此线程的 run() 方法。
5、通过继承 Thread 的方法和实现 Runnable 接口的方式创建多线程,哪个好?
实现Runable接口好,原因有两个:
①、避免了Java单继承的局限性
②、适合多个相同的程序代码去处理同一资源的情况,把线程、代码和数据有效的分离,更符合面向对象的设计思想。
6、两种常见的线程控制方法
- sleep():使当前正在执行的线程暂停指定的毫秒数,也就是进入休眠的状态。
需要注意的是,sleep 的时候要对异常进行处理。
try {//sleep会发生异常要显示处理
Thread.sleep(20);//暂停20毫秒
} catch (InterruptedException e) {
e.printStackTrace();
}
- join():等待这个线程执行完才会轮到后续线程得到cpu的执行权,使用这个也要抛出异常。
ArrayList<String>list=new ArrayList<>();
MyThread m1=new MyThread(list);
MyThread m2=new MyThread(list);
m1.start();
try {
m1.join();
} catch (InterruptedException e) {
e.printStackTrace();
}
m2.start();
结果:等待m1执行完才会轮到m2
Thread-0aaa0aaa0
Thread-0aaa1aaa1
Thread-0aaa2aaa2
Thread-0aaa3aaa3
Thread-0aaa4aaa4
Thread-0aaa5aaa5
Thread-0aaa6aaa6
Thread-0aaa7aaa7
Thread-0aaa8aaa8
Thread-0aaa9aaa9
Thread-0aaa10aaa10
Thread-0aaa11aaa11
Thread-0aaa12aaa12
Thread-0aaa13aaa13
Thread-0aaa14aaa14
Thread-0aaa15aaa15
Thread-0aaa16aaa16
Thread-0aaa17aaa17
Thread-0aaa18aaa18
Thread-0aaa19aaa19
Thread-1aaa0aaa0
Thread-1aaa1aaa1
Thread-1aaa2aaa2
Thread-1aaa3aaa3
Thread-1aaa4aaa4
Thread-1aaa5aaa5
Thread-1aaa6aaa6
Thread-1aaa7aaa7
Thread-1aaa8aaa8
Thread-1aaa9aaa9
Thread-1aaa10aaa10
Thread-1aaa11aaa11
Thread-1aaa12aaa12
Thread-1aaa13aaa13
Thread-1aaa14aaa14
Thread-1aaa15aaa15
Thread-1aaa16aaa16
Thread-1aaa17aaa17
Thread-1aaa18aaa18
Thread-1aaa19aaa19
附一张线程的生命周期