①进程和线程的概念
进程:操作系统结构的基础,是一次程序的执行;是一个程序及其数据在处理机上顺序执行时所发生的活动;
线程:在进程中独立运行的子任务
*通过查看Windows任务管理器中的列表,完全可以将内存中的exe文件理解成进程,进程是受操作系统管理的基本运行单元,比如QQ.exe就是一个进程,QQ.exe运行时就有很多的子任务在同时运行,那些子任务就可以理解为“线程”在工作
②多线程的优点
如图所示,任务1和任务2是两个完全独立的任务,图1中,任务2是在10秒后运行,任务1则子一秒后运行,在单线程中,如果任务2在任务1之前执行,那么任务2虽然执行时间只有一秒,但必须等待任务1执行完才可以执行,二图2中,在多线程中,CPU完全可以在任务1和任务2之间来回切换,任务2不需要等到10秒后再运行,系统的运行效率大大提升。
③多线程的两种实现方式:
1.继承Thread类
2.实现Runnable接口
继承Thread类示例:
public class MyThread extends Thread{
@Override
public void run(){
super.run();
System.out.println("MyThread");
}
}
public class Run{
public static void main(String args[]){
MyThread myThread = new MyThread();
myThread.start();
System.out.println("运行结束");
}
}
运行结果:
实现Runnable接口:
public class MyRunnable implements Runnable{
@Override
public void run(){
System.out.println("myRunnable");
}
}
public class Run{
public static void mian(String[] args){
Runnable runnable runnable = new MyRunnable();
Thread thread = new Thread(runnable);
thread.start();
System.out.println("运行结束");
}
}
运行结果:
④实例变量和线程安全(synchronized)
1.自定义线程类中的实例变量针对其他线程可以有共享与不共享之分
不共享示例:
public MyThread extends MyThread{
private int count =5;
public MyThread(String name){
super();
this.setName(name);
}
@Override
public void run(){
super.run();
while(count>0){
count --;
System.out.println("由"+this.currentThread().getName()+"计算,count=" + count);
}
}
}
public class Test{
public static void main(String args[]){
MyThread a = new MyThread("A");
MyThread b = new MyThread("B");
MyThread c = new MyThread("C");
a.start();
b.start();
c.start();
}
}
output:
共享示例:
public class MyThread {
private int count =5;
@Override
public void run(){
super.run();
count --;
System.out.println("由" + this.currentThread().getName()+ "计算,count = " + count;
}
}
public class Test{
public static void main(String args[]){
MyThread myThread = new MyThread();
Thread a = Thread(myThread,"A");
Thread b = Thread(myThread,"B");
Thread c = Thread(myThread,"C");
a.start();
b.start();
c.start();
}
}
output:
输出结果看出,A,C同时处理产生“非线程安全问题”
*非线程安全:指多个线程对同一个对象中的同一个实例变量进行操作时会出现值被更改,值不同步的的情况。
2.synchronized关键字
synchronized可以在任意对象及方法上加锁,而加锁的这段代码称为“互斥区”或“临界区”
示例代码:
public class MyThread {
private int count =5;
@Override
synchronized public void run(){
super.run();
count --;
System.out.println("由" + this.currentThread().getName()+ "计算,count = " + count;
}
}
public class Test{
public static void main(String args[]){
MyThread myThread = new MyThread();
Thread a = Thread(myThread,"A");
Thread b = Thread(myThread,"B");
Thread c = Thread(myThread,"C");
a.start();
b.start();
c.start();
}
}
output:
⑤currentThread()方法
currentThread()方法可返回代码段正在被哪个线程调用的信息
public class Run{
public static void main(String args[]){
System.out.println(Thread.currentThread().getName());
}
}
⑥isAlive()方法
判断当前线程是否处于活动状态
public class MyThread extends Thread{
@Override
public void run(){
System.out.println("run=" +this.isAlive());
}
}
public class Run{
public static void main(String args[]){
MyThread mythread = new MyThread();
System.out.println("begin==" + mythread.isAlive());
mythread.start();
System.out.println("end==" + mythread.isAlive());
}
}
⑦sleep()方法
在指定的毫秒数内让当前“正在执行的线程”休眠(暂停执行)
⑧getId()方法
取得线程的唯一标识
public class Test{
public static void main(String args[]){
Thread runThread = Thread.currentThread();
System.out.println(runThread.getName() + " "+ runThread.getId());
}
}
⑨停止线程
1.interrupt():仅仅是在当前线程中大了一个停止的标记,并不是真的停止线程
2.this.interrupted():测试当前线程是否已经中断。
3.this.isInterrupted():测试线程是否已经中断。
⑩线程的优先级
1.在操作系统中,线程可以划分等级,优先级较高的线程得到的CPU资源较多,也就是CPU优先执行优先级较高的线程对象中的任务
2.在java中,线程的优先级氛围1~10这10个级别,小于1或者大于10会抛出异常 illegalArgumentExcepton().
3.线程的优先级具有继承性,比如A线程启动B线程,则B线程的优先级与A是一样的
*守护线程:守护线程是一种特殊的线程,它的特性有陪伴的含义,当进程中不存在非守护线程了,则守护线程自动销毁。典型的引用就是GC(垃圾回收器)
参考:《Java多线程编程核心技术》--机械工业出版社 高洪岩 著