创建线程
方法一:继承Thread类
步骤
1. 定义一个类继承Thread类;
2. 覆盖Thread类中的run方法;
3. 直接创建Thread的子类对象创建线程;
4. 调用start方法开启线程并调用线程的任务run方法执行;
class MyThread extends Thread{
private String name;
public MyThread(String name) {
this.name = name;
}
@Override
public void run() {
for(int x=0; x<10; x++) {
System.out.println(name+"....x="+x+".....name="+Thread.currentThread().getName());
}
}
}
public class Main {
public static void main(String[] args) throws MyException {
MyThread t1 = new MyThread("kevin");
MyThread t2 = new MyThread("carol");
t1.start();
t2.start();
}
}
方法二:实现Runnable接口
步骤
1. 定义类实现Runnable接口。
2. 覆盖接口中的run方法,将线程的任务代码封装到run方法中。
3. 通过Thread类创建线程对象,并将Runnable接口的子类对象作为Thread类的构造函数的参数进行传递,即,在线程对象创建时就必须明确要运行的任务。
4. 调用线程对象的start方法开启线程。
实现Runnable接口创建线程的方式比较常用,它的好处:
1. 将线程的任务从线程的子类中分离出来,进行了单独的封装。
2. 避免了java单继承的局限性。
class MyThread implements Runnable{
private String name;
public MyThread(String name) {
this.name = name;
}
@Override
public void run() {
for(int x=0; x<10; x++) {
System.out.println(name+"....x="+x+".....name="+Thread.currentThread().getName());
}
}
}
public class Main {
public static void main(String[] args) throws MyException {
Thread t1 = new Thread(new MyThread("kevin"));
Thread t2 = new Thread(new MyThread("carol"));
t1.start();
t2.start();
}
}
线程状态
线程安全
产生的原因
- 多个线程在操作共享的数据。
- 操作共享数据的线程代码有多条。
如何解决
- 方式:同步代码块、同步函数、Lock;
- 原理:就是将多点操作封装起来,一个线程操作的时候,其他线程时不可以参与运算的;
- 同步的好处:解决了线程的安全问题;
- 同步的弊端:相对降低了效率,因为同步外的线程的都会判断同步锁;
- 同步的前提:同步中必须有多个线程并使用同一个锁。
//同步代码块的格式:
//同步代码块的锁是任意的对象。
synchronized(对象){
//需要被同步的代码;
}
//同步函数
//同步函数的使用的锁是this
public synchronized void show(){
//需要被同步的代码;
}