前言:
今天就简单分享下java多线程的特性。多线程的优势有很多,他可以以比较小的性能开销来同时完成更多的任务。同时他也是个无法控制的双刃剑。多线程因为变量共享,会导致诸多问题。那么就来了解下什么是多线程
什么是单线程:
下面有两个个简单的for循环
public class Demo {
public static void main(String arg[]){
for (int i = 0; i <5 ; i++) {
System.out.println("一循环"+i);
}
for (int i = 0; i <5 ; i++) {
System.out.println("二循环"+i);
}
}
}
我们能知道,结果会是第一个循环打印完了再打印第二个。这样的顺序执行就叫做单线程

输出结果
同一个线程,代码至上而下执行,这个就不多介绍了
多线程方法一:继承Thread类
下面介绍的开启多线程方法就是使一个类继承Thread类,继承了之后,需要重写父类的run方法。这个方法里面就实现需要多线程执行的方法体
class Runner extends Thread{
private String name;
//构造方法,初始化名字
public Runner(String name){
this.name=name;
}
@Override
public void run() {
//重写父类run方法
for (int i = 0; i <10 ; i++) {
System.out.println(name+" --->"+i);
}
}
}
这样写了还不算完,在main方法中的调用也有些不一样
public class Demo {
public static void main(String arg[]){
//实例化两个Runner对象
Thread runner1=new Runner("线程1");
Thread runner2=new Runner("线程2");
//分别调用父类的start方法
runner1.start();
runner2.start();
}
}
大家看代码肯定能看出来,我这里是开启两个线程去执行那个for循环。那么我们来看看执行的效果

多线程执行结果
从执行结果来看,前几次打印还比较有规律,再后面就有些混乱了。这也是多线程的特性。当两个线程开启,计算机是随机执行了。当数据比较小的时候,看不太出来,当数据大了。执行的结果会有较大的偏差
多线程方法二:继承接口Runnable
除了上面写到的继承Thread类之外还有个方式就是继承Runnable接口,并实现run方法。注意,不同的是一个是类,一个是接口。java也是一个单继承的语言。那么当你的业务类继承了Thread之后,就无法继承别的类了。这样在开发中就很不方便。不过Runnable就不会有这样的问题
使用方法也有些许区别
public class Demo {
public static void main(String arg[]){
//实例化个Runner对象
Runner runner=new Runner();
new Thread(runner,"线程1").start();
new Thread(runner,"线程2").start();
}
}
class Runner implements Runnable{
@Override
public void run() {
//实现接口方法
for (int i = 0; i <10 ; i++) {
System.out.println(Thread.currentThread().getName()+" --->"+i);
}
}
}
执行结果也同样是混乱的

多线程执行结果1
总结:
总的来说Runable会比Thread 更有优势,除了提到过的单继承的问题。Thread每开一个线程都会去实例化一个业务类的对象,这样的性能开销也会比较大。
多线程在提高效率的同时,因为共享代码共享变量。也会导致很多问题,所以在java中线程安全是一个绕不开的话题。如果我的博客有什么写的不对的地方,欢迎大神指点。谢谢