一、创建线程的两种方式:
1、继承thread类;重写run方法。(单继承,直接写业务逻辑)
public class Demo1 extends Thread{
@Override
public void run{
for(int=i; i<100; i++){
system.out.println(“自定义线程:”+i);
}
}
}
2、实现Runnable接口,运行run方法来实现线程。
class Demo2 implement Runnable{
@Override
public void run() {
while (true) {
synchronized ("锁") {
if (ticket > 0) {
System.out.println(Thread.currentThread().getName() + ":卖出了第" + ticket + "张");
ticket--;
try {
Thread.sleep(100);
} catch (InterruptedException e) {
e.printStackTrace();
}
} else {
System.out.println("票买完了");
break;
}
}
}
}
public class TestSaleTicket01 { //利用start来启动线程
public static void main(String[] args) {
Demo2 run = new Demo2();
new Thread(run,"yi").start();
new Thread(run,"er").start();
new Thread(run,"san").start();
}
}
}
二、多线程:
1、多线程的作用:
1)发挥多核cpu的优势;多核CPU让多段逻辑同时工作,实现多线程。
2)防止阻塞;多条线程运行时,有一个线程读取数据阻塞,不会影响其他任务的执行。
3)便于建模。把一个大任务A分解成几个小任务,分别建立程序模型,并通过多线程分别运行这几个任务。
2、创建线程:1)继承thread类 2)实现Runnable接口,建议使用第二种方式,因为实现接口的的方式比继承类的方式更加灵活,也能减少程序之间的耦合度,面向接口也是设计模式的6大原则的核心。
3、start()方法和run()方法的区别:
线程开启用的是start方法,只有调用了start 的方法,才会表现出多线程的特性,不同线程的run()方法中的代码块交替执行。如果只调用run方法,那么代码块还是同步执行的,必须等待一个线程中的代码执行完毕后,另一个线程才能执行其run方法里面的代码。
4、Runnable接口和Callable接口的区别
Runnable接口中的run()方法返回值是void,它做的事情只是单纯的执行方法。
但callable接口中的call()方法是有返回值的,是一个泛型,和future、futuretask配合使用可以获取异步执行的结果。Callable(产生结果)功能更强大,被线程执行后,可以返回值;Future(获取结果)可以拿到异步执行任务的返回值。
例如:当某条线程执行时,我们期望的数据是否已经复制完毕无法得知时;如果用Runnable只能等待线程执行完毕,而Callable+future可以获取多线程运行结果,可以在等待时间太长没有获取到结果需要数据时取消该线程的任务。
网友评论