线程,程序和进程是经常容易混淆的概念。
程序:就是有序严谨的指令集
进程:是一个程序及其数据在处理机上顺序执行时所发生的活动
线程:程序中不同的执行路径,就是程序中多种处理或者方法。
线程有两种方法实现
一:继承Thread 覆盖run方法
package Thread;public class Thread1 {
public static void main(String[] args){
MyThread1 thread1=new MyThread1();
thread1.setName("线程1");
thread1.start();MyThread1 thread2=new MyThread1();
thread2.setName("线程2");
thread2.start();for(int i=0;i<5;i++)
System.out.println("主线程正在执行");
}}
class MyThread1 extends Thread{
public void run(){
for(int i=0;i<20;i++)
{
System.out.println(Thread.currentThread().getName()+"正在执行"+i);
}
}
}
由于线程是由CPU随机分配的,所以输出结果中 会发现 各线程的执行顺序也是随机的。
部分输出结果:
主线程正在执行
主线程正在执行
线程2正在执行0
线程2正在执行1
线程2正在执行2
线程2正在执行3
线程2正在执行4
线程1正在执行0
线程2正在执行5
线程1正在执行1
线程2正在执行6
2:实现接口Runnable 实现run方法
package Thread;public class Runnable1 {
//实际开发推荐使用该方法
public static void main(String[] args){
MyThread2 rthread=new MyThread2();
//由于接口中的方法都是抽象的 所以无法直接调用start()
Thread thread1=new Thread(rthread);
Thread thread2=new Thread(rthread);thread1.setName("线程1");
thread2.setName("线程2");thread1.start();
thread2.start();for(int i=0;i<20;i++)
System.out.println("主线程正在执行");
}}
//通过实现接口Runnable实现
class MyThread2 implements Runnable{
public void run(){
for(int i=0;i<20;i++)
{
System.out.println(Thread.currentThread().getName()+"正在执行"+i);
}
}
}
部分输出结果:
主线程正在执行
主线程正在执行
线程1正在执行0
线程2正在执行0
线程1正在执行1
线程2正在执行1
线程的使用就这么简单,不过在实际开发中一般使用第二种方法好点.
从程序可以看出,由于是随机分配CPU所以无法实现线程的执行的顺序,那有办法吗?
有,就是设置优先级
package Thread;public class ThreadPrority {
public static void main(String[] args){
MyThread3 rthread=new MyThread3();Thread thread1=new Thread(rthread);
Thread thread2=new Thread(rthread);thread1.setName("线程1");
thread2.setName("线程2");thread1.setPriority(1);//设置优先级 默认是5
thread2.setPriority(9);thread1.start();
thread2.start();
}
}
//通过实现接口Runnable实现
class MyThread3 implements Runnable{
public void run(){
for(int i=0;i<30;i++)
{
System.out.println(Thread.currentThread().getName()+"正在执行"+i);
}
/*设置了优先级 不代表优先级高的就一定会执行 只有更有几率从CPU那分取到。
* */
}
}
输出结果:
线程1正在执行0
线程2正在执行0
线程1正在执行1
线程2正在执行1
线程1正在执行2
线程2正在执行2
线程1正在执行3
线程2正在执行3
线程1正在执行4
线程2正在执行4
线程1正在执行5
线程2正在执行5
线程1正在执行6
线程2正在执行6
这里你一定会有疑问 这不是没变么,主要是这里循环的次数太低 而计算机运算的速度太快,想要看效果 可以把循环次数调高些。
这些就是线程的基本操作。线程还可以睡眠,在睡眠的时间段CPU不会让调用它的对象参与竞争。
package Thread;public class ThreadSleep {
public static void main(String[] args){
MyThread4 rthread=new MyThread4();
Thread thread=new Thread(rthread);
thread.setName("线程");
thread.start();
}
}
//通过实现接口Runnable实现
class MyThread4 implements Runnable{
public void run(){
for(int i=0;i<100;i++)
{
System.out.println(Thread.currentThread().getName()+"正在执行"+i);
try {
Thread.sleep(1000);//线程睡眠1s
} catch (Exception e) {
// TODO: handle exception
System.out.println("线程出错");
}
/*只得注意的是 这里要处理线程睡眠的异常,而且不能向上一级throws
*因为throws,是其调用类的父类或者其实现的接口中有该方法,才能向上throws
*这里实现的Runnable里面的抽象方法中并没有throws方法
*所以这里如果throws的话 会出错 只能用try...catch来处理
*/
}
}
}
输出结果:
线程正在执行0
线程正在执行1
线程正在执行2
线程正在执行3
线程正在执行4
它会隔1秒输出一句。Tread.Sleep(1000);这里的1000是毫秒 同时这里要处理异常,值得注意的是。这里的异常只能用try...catch。
而且不能向上一级throws
因为throws,是其调用类的父类或者其实现的接口中有该方法,才能向上throws
这里实现的Runnable里面的抽象方法中并没有throws方法
所以这里如果throws的话 会出错
只能用try...catch来处理
就像 线程不能直接调用run方法,而要调用start一样,因为接口中的方法是抽象的。
在Thread里面可以调用run方法,但是它并不会另开线程,而是把run直接调用,相当于在主线程运行一个函数而已。
java进阶06 线程初探,码迷,mamicode.com