发表于: 2017-12-12 23:40:14
1 642
今天做的事情:
学习一下基础中的多线程。言简意赅,多线程就是一个程序在运行时产生了不止一个线程。多线程中有进程和线程,进程是一个正在执行的程序,每一个进程执行都有一个执行顺序,也是控制单元,而线程,就是进程中的一个控制单元。
线程和进程一样是分为五个阶段:创建,就绪,运行,堵塞,终止。
在java中,想要实现多线程,有两种手段,一种是继续Thread类,一种是实现Runable接口。
并行与并发:
并行:多个cpu实例或者多台服务器同时执行一段处理逻辑,是真正的同时运行。
并发:通过cpu调度算法,让用户看起来是同时执行,实际上从cpu操作层面不是真正的同时,并发往往在场景中有共用的资源,针对这个公有的资源的瓶颈,会用TPS和QPS来反应这几个系统的处理时间。
- 线程安全:经常用来描绘一段代码。指在并发的情况之下,该代码经过多线程使用,线程的调度顺序不影响任何结果。这个时候使用多线程,我们只需要关注系统的内存,cpu是不是够用即可。反过来,线程不安全就意味着线程的调度顺序会影响最终结果,如不加事务的转账代码:
void transferMoney(User from, User to, float amount){ to.setMoney(to.getBalance() + amount); from.setMoney(from.getBalance() - amount); }
- 同步:Java中的同步指的是通过人为的控制和调度,保证共享资源的多线程访问成为线程安全,来保证结果的准确。如上面的代码简单加入
@synchronized
关键字。在保证结果准确的同时,提高性能,才是优秀的程序。线程安全的优先级高于性能。
看了这么多概念性的东西,我也快受不了了。上代码试试
第一种实现方式,继承Thread
class Thread1 extends Thread {
private String name;
public Thread1(String name) {
this.name = name;
}
@Override
public void run() {
for (int i = 0; i < 5; i++) {
System.out.println(name + "运行 : " + i);
try {
sleep((int) Math.random() * 10);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
public class Thread2 {
public static void main(String[] args) {
Thread1 mTh1=new Thread1("A");
Thread1 mTh2=new Thread1("B");
mTh1.start();
mTh2.start();
}
}
第一次运行:
A运行 : 0
A运行 : 1
A运行 : 2
A运行 : 3
B运行 : 1
A运行 : 4
B运行 : 2
B运行 : 3
B运行 : 4
第二次:
A运行 : 0
B运行 : 0
A运行 : 1
B运行 : 1
A运行 : 2
B运行 : 2
A运行 : 3
B运行 : 3
A运行 : 4
B运行 : 4
在程序运行main的时候,java虚拟机启动一个进程,主线程main在main()调用时候被创建,随着调用MitiSay的两个队象的start方法,另外两个线程也启动了,这样,整个应用就在多线程下运行。
注意:start()方法的调用并不是立即执行多线程代码,而是使得该线程为可运行的Runnable,什么时候运行时操作系统决定的。从运行结果来看,多线程是乱序执行的,因此,乱序执行的代码才有必要设计为多线程。
Thread.sleep()方法调用目的是不让当前线程独自霸占该进程所获取的CPU资源,以留出一定时间给其他线程执行的机会。实际上所有的多线程代码执行顺序都是不确定的,每次执行结果都是随机的。
第二种方式: 实现Runnable
class Thread4 implements Runnable{通过实现Runnable接口,使得该类有了多线程的特征,run方法是一个多线程的约定,所有的多线程代码都在run方法里面,Thread类实际上也是实现Runnable接口
private String name;
public Thread4(String name) {
this.name=name;
}
@Override
public void run() {
for (int i = 0; i < 5; i++) {
System.out.println(name + "运行 : " + i);
try {
Thread.sleep((int) Math.random() * 10);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
public class Thread3 {
public static void main(String[] args) {
new Thread(new Thread4("C")).start();
new Thread(new Thread4("D")).start();
}
}
在启动多线程时,需要先通过Thread类的构造方法 Thread(Runnable target) 构造出对象,然后调用Thread对象的start()方法来运行多线程代码。 实际上所有多线程代码都是通过运行Thread的start()方法来运行的。所以,虽然实现方式不同,一个继承Thread,一个实现Runnable,同样需要复写run方法,start来启动。
总结:
实现Runnable接口比继承Thread类所具有的优势:
1):适合多个相同的程序代码的线程去处理同一个资源
2):可以避免java中的单继承的限制
3):增加程序的健壮性,代码可以被多个线程共享,代码和数据独立
跑完代码,再来看图解:
关于多线程,学习到这里,博客链接:http://www.mamicode.com/info-detail-517008.html
关于mysql优化的东西:
今天还总结了一下,自己所学的东西,准备做PPT,还有欠缺的东西,基础等等。
遇到的问题:
无
收获:
在很久之前已经做过多线程例子,没经常用就忘了,这次再拾起来,看了看关于sql优化和mysql优化,复习以前学习的东西。
评论