首先是一些简单的对于进程和线程的介绍:
1.进程与进程间相互独立,互不干涉。
举例:
手机和电脑上的软件程序就是进程。
2.线程在进程中,一个进程可以有多个进程,多线程可以提高电脑运行效率,一个进程中的线程共享堆区和方法区,但栈区独立,一个线程一栈。
举例:
在播放电影时画面和声音并不是同步的,而是两个线程在乱序执行,但由于人无法分辨才显得同步,这是多线程的一种。
多线程的两种构建方式
以代码举例:
1.扩展Runnable
class test implements Runnable{
@Override
//线程执行内容全写在run()中
public void run() {
//执行内容
}
}
2.继承Thread
class test extends Thread{
public void run() {
//执行内容
}
}
二者有区别,扩展Runnable比继承Thread更加灵活,其中一个原因是扩展后还能继承其他类,所以比较推荐扩展Runnable。
下文中就以扩展Runnable举例,一些多线程基础操作
以代码举例:
public class Main {
public static void main(String[] args) {
Thread t=new Thread(new test());
t.start();
//start(),将线程转为可运行状态,后续执行由系统分配,不可人为控制
//线程运行时会执行中的内容run();
}
}
class test implements Runnable{
@Override
public void run() {
for (int i = 0; i < 8; i++) {
System.out.println("t:"+i);
}
}
}
执行效果:
t:0
t:1
t:2
t:3
t:4
t:5
t:6
t:7
以下面的代码验证多线程乱序执行:
public class Main {
public static void main(String[] args) {
Thread t1=new Thread(new coke());
Thread t2=new Thread(new sit());
t2.start();
t1.start();
}
}
class test1 implements Runnable{
@Override
public void run() {
for (int i = 0; i < 8; i++) {
System.out.println("t1:"+i);
}
}
}
class test2 implements Runnable{
@Override
public void run() {
for (int i = 0; i < 8; i++) {
System.out.println("t2:"+i);
}
}
}
执行效果:
t2:0
t2:1
t1:0
t2:2
t1:1
t1:2
t2:3
t1:3
t2:4
t1:4
t1:5
t1:6
t2:5
t1:7
t2:6
t2:7
//从这里可以看出多线程执行没有规律。
如果线程中执行内容太多,可能会出现主线程已经结束而子线程还未结束。以代码举例:
public class Main {
public static void main(String[] args) {
System.out.println("-------------");
Thread t1=new Thread(new test());
Thread t2=new Thread(new test2());
t2.start();
t1.start();
System.out.println("-------------");
}
}
class test1 implements Runnable{
@Override
public void run() {
for (int i = 0; i < 8; i++) {
System.out.println("t1:"+i);
}
}
}
class test2 implements Runnable{
@Override
public void run() {
for (int i = 0; i < 8; i++) {
System.out.println("t2:"+i);
}
}
执行效果:
-------------
-------------
t1:0
t2:0
t1:1
t1:2
t2:1
t2:2
t1:3
t1:4
t2:3
t2:4
t1:5
t1:6
t2:5
t1:7
t2:6
t2:7
//从打印结果可看出,主线程打印先于子线程完成
这里引出了一个join()方法,它可让子线程等待主线程结束。
将Main改为:
public class Main {
public static void main(String[] args) {
System.out.println("-------------");
Thread t1=new Thread(new test());
Thread t2=new Thread(new test2());
t2.start();
t1.start();
try {
t1.join();
} catch (InterruptedException e) {
throw new RuntimeException(e);
}
try {
t2.join();
} catch (InterruptedException e) {
throw new RuntimeException(e);
}
System.out.println("-------------");
}
}
执行效果:
-------------
t2:0
t1:0
t2:1
t2:2
t2:3
t2:4
t2:5
t2:6
t2:7
t1:1
t1:2
t1:3
t1:4
t1:5
t1:6
t1:7
-------------
线程还有优先级的概念,优先级高的线程得到系统调度的机会更大,有兴趣可去查,优先级的范围是1到10。
再介绍两个方法,分别是sleep()和yield()
sleep(long time),括号中是以毫秒为单位的一个值,如果线程中使用它会在输入时间内停止运行,在sleep()结束后才有机会被执行,可参考:
class test implements Runnable{
@Override
public void run() {
for (int i = 0; i < 8; i++) {
System.out.println("t1:"+i);
try {
sleep(1000);
} catch (InterruptedException e) {
throw new RuntimeException(e);
}
}
}
}
yield()和sleep()有点像都是让出执行空间,但是yield()是随机执行也就是说在自己让出执行空间后自己还是有机会被执行,但是用了sleep()用了自己
在规定时间内不能再被执行。
以上是这几天所学到的,有偏差和不足,仅做为学习记录。