多线程:
1.两种创建方式
:
1.1.继承Thread类:
1.1.1创建方法:
写一个继承于Thread类的子类;重写run方法;创建本类的对象;用对象调用start方法。这样四步骤就创建了多线程。
例如:
```java
//1.写一个继承于Thread类的子类
public class ThreadThreadTest extends Thread{
//2.重写run方法
@Override
public void run() {
//顺便写一个冒泡排序
int arr[] = new int[]{10,2,-20,50,5,30};
System.out.println("排序前为:"+ Arrays.toString(arr));
for(int i =0;i<arr.length-1;i++){
for(int j = 0;j<arr.length-i-1;j++){
if(arr[j] > arr[j+1]){
int temp = arr[j];
arr[j] = arr[j+1];
arr[j+1] = temp;
}
}
}
System.out.println("排完序后为:"+ Arrays.toString(arr));
}
public static void main(String[] args) {
//3.创建本类的对象
ThreadThreadTest ttt = new ThreadThreadTest();
//4.调用start方法
ttt.start();
}
}
## 1.1.2注意事项
①不能直接调run方法,这样不能启动线程
②需要另外一个线程时需要重新new对象去调线程(调用相同的方法),在继承类这里就是要重复创建线程。在这里使用多线程就需要使用类创建多对象。
③因为这里创建的对象可能不止一个,所以如果共享数据的创建对象时就创建了多个那么就造成了没有共享数据,大家自己都是自己的数据,所以这时可以把共享的数据用static写成静态变量,这样多个线程就可以共享同一个数据了。用static共享一份数据,但是有线程安全问题,后面会讲解决线程安全问题。
继承的方式解决同步方法要慎用(因为监视器为this,可能不唯一要慎用。)
1.1.3给线程命名:
Thread.current方法就可以使用自定义的名字。
## 1.2实现Runnable接口:
创建多线程的方式二:实现Runnable接口
创建一个实现Runnable接口的类;重写run方法;创建实现类的对象;创建Thread类的对象,并把实现类的对象作为参数放入创建的Thread中作为实参;用Thread的对象调用start方法。使用这五部既可以创建用实现Runnable的接口的方式创建多线程。
```java
//1.创建类实现runnable接口
class MThread implements Runnable{
//2.重写run方法
@Override
public void run() {
int arr[] = new int[]{10,5,62,-12,3,96,78,50};
System.out.println("排序前:"+ Arrays.toString(arr));
for(int i = 0;i<arr.length-1;i++){
for(int j =0;j<arr.length-i-1;j++){
if(arr[j]>arr[j+1]){
int temp = arr[j];
arr[j] = arr[j+1];
arr[j+1] = temp;
}
}
}
System.out.println(Thread.currentThread().getName()+"排序后:"+Arrays.toString(arr));
}
}
public class ThreadTest {
public static void main(String[] args) {
//3.创建实现类的对象
MThread mt = new MThread();
//4.将实现类的对象作为参数传递到Thread类的构造器中,创建Thread类的对象
Thread th1 = new Thread(mt);//此时的线程为th1(谁start谁就是线程)
th1.setName("线程1:");
//5.用Thread类调用start方法(①启动线程;②调用run方法---》调用了runnable中target的run方法)
th1.start();
//在启动一个线程(共用一个对象)
Thread th12= new Thread(mt);//此时的线程为th1(谁start谁就是线程)
th12.setName("线程2:");
th12.start();
}
}
1.3、比较两种创建线程的方式
在开发中,优先使用实现Runnable接口的方式
主要有两种原因:1.实现的方式没用类的单继承性;
2.实现的方式更适合来处理多个线程共享数据的情况。
对于两者而言:联系:public class Thread implements Runnable
相同点:两种方式都需要重写run(),将线程要执行的逻辑声明在run中。