1、进程和线程的区别
进程是操作系统结构的基础,是一次程序的执行;是一个程序及其数据在处理机上顺序执行所发生的活动;是一个程序在一个数据集合上运行的过程;是系统进行资源分配和调度的一个独立单位。
线程是在进程中独立运行的子任务。
2、Thread类
- 构造方法
构造方法 | 使用方式 |
---|---|
Thread() | 分配新的线程对象 |
Thread(String name) | 分配新的线程对象,name为线程名称 |
Thread(Runnable runnable) | 分配新的线程对象,runnable为其运行对象 |
Thread(Runnable runnable,String name) | 分配新的线程对象,runnable为其运行对象,name为线程名 |
Thread(ThreadGroup group,Runnable runnable) | 分配新的线程对象,runnable为其运行对象,作为group所引用的线程组的一员 |
3、线程实现的方式
3.1 继承Thread类
public class MyThread extends Thread
{
@Override
public void run()
{
super.run();
}
}
public class Run
{
public static void main(String[] args)
{
MyThread mythread = new MyThread();
mythread.start();
}
}
3.2 实现Runnable接口
- 因为java中的继承是单根继承,所以使用该方法可以实现多线程技术。
public class MyRunnable implements Runnable
{
@Override
public void run()
{
super.run();
}
}
public class Run
{
public static void main(String[] args)
{
MyRunnable myrunnable = new MyRunnable();
Thread thread = new Thread(myrunnable);
thread.start();
}
}
4、线程的随机性
- 使用start()方法启动线程,只是使线程进入就绪状态,只有当线程调度器将其设置为当前线程,线程才会进入运行状态,执行其run()线程体。
- 执行start()方法的顺序不代表线程运行的顺序,执行顺序不定。
5、常用线程方法
- currentThread(): 返回当前代码段被哪个线程调用的信息。
- isAlive(): 判断当前线程是否存活,线程处于运行状态或者就绪状态均返回true。
- sleep(): 使当前正在执行的线程休眠若干毫秒,指向this. currentThread()返回的线程。
- yield(): 使线程放弃当前的CPU资源,将其让给其他任务先使用,因此会导致线程运行时间变长,增加时间不定。
6、不安全的线程方法
6.1 停止线程的方法
- run()方法完成后线程自行终止。
- stop()方法强制结束进程,作废过期,不安全!
调用stop()方法中停止线程会抛出java.lang.ThreadDeath异常;也有可能使得一些清理工作无法进行;对锁定的对象进行了“解锁”,导致数据得不到同步的处理,造成数据不一致。
- interrupt()方法中断进程。
调用interrupt()方法仅仅只是在当前线程中打了一个停止的标记,并不是马上停止线程。
6.2 interrupt()方法
6.2.1 判断线程状态的方法
- this.interrupted(): 测试当前线程是否已经是中断状态,执行后具有将状态标志清除为false的功能。
- this.isInterrupted(): 静态方法,测试线程Thread对象是否已经是中断状态,但不清除状态标志。
6.2.2 停止线程的方法
public class Run
{
public static void main(String[] args)
{
try
{
MyThread thread = new MyThread();
thread.start();
Thread.sleep();
thread.interrupt();
}
catch(InterruptedException e)
{
e.printStackTrace();
}
}
}
- for循环判断法
public class MyRunnable implements Runnable
{
@Override
public void run()
{
super.run();
for(int i=0; i<5000;i++)
{
if(this.interrupted)
{
break;
}
}
//此部分代码会继续执行
}
}
- 抛异常法
public class MyRunnable implements Runnable
{
@Override
public void run()
{
super.run();
for(int i=0; i<5000;i++)
{
if(this.interrupted)
{
throw new InterruptedException();
//此处也可以直接使用return,建议使用抛异常法,可以对异常信息做处理,也不会造成污染
}
}
}
}
6.2 suspend()和resume()方法
用于中止和恢复线程,过期废弃。
缺点:
1、造成公共同步对象的独占,使其他线程无法访问公共同步对象。
2、因为线程的暂停导致数据不同步。
7、线程的优先级
- 设置优先级使用setPriority()方法,分为1~10一共10个等级。
- 优先级具有继承性,若线程A由线程B启动,则两者优先级一致。
- CPU尽可能将执行资源让给优先级高的线程,但不能保证高优先级的一定可以全部先执行完,只是在大概率能先执行,具有不确定性和随机性。