并行和并发的区别:
并行:同时处理(一边看电视一边吃饭)
并发:多个任务只能处理一个(先煮面、再放料包、再吃饭、洗碗)
一个线程 和 多线程程序:
一个程序同时可以执行多个任务,通常一个任务成为一个线程,可以运行一个以上线程的程序叫做多线程程序。
多线程与多进程的区别在哪里呢?
每一个进程拥有自己一整套变量
线程之间共享数据,共享变量可以使线程之间的通信比进程之间更加的有效
使用线程给其他任务提供机会:
给一个单独的线程执行一个简单的任务:
方法一:调用Runnable接口,实现该接口的run方法
1)现将该类实现Runnable接口,将需要执行的代码写在run方法中(继承这个接口,实现该接口的run方法)
2)创建Runnable对象,因为Runnable是接口,所以后面需要实现接口的类,由Runnable创建Thread对象(多态)
3)启动线程(.start() )
public class a implements Runnable{
public void run(){
for(int i=0;i<1000;i++){
System.out.println(Thread.currentThread().getName()+i+"-------");
}
}
public static void main(String[]args){
Runnable r=new a();
Thread t=new Thread(r);
t.start();
for(int i=0;i<1000;i++){
System.out.println(i);
}
}
}
2:继承Thread类,重写run方法,构建子类对象,调用start()方法
import threadtest.ThreadText;
public class ThreadTest extends Thread {
public void run(){
for(int i=0;i<100;i++){
System.out.println(Thread.currentThread().getName()+i);
}
}
public static void main(String[]args){
ThreadTest threadText=new ThreadTest();
for(int i=0;i<100;i++){
System.out.println(i+">>>>>");
}
threadText.start();
}
}
现在尽量不要用第二种方法,因为一个类只能单继承
不管是调用Thread类还是Runnable的run方法,直接调用run方法,只会执行同一个线程的任务,不会启动任务,只要调用Thread.start()方法,就能创建一个执行run方法的新线程。
interrupt() 和interrupted()和Isinterrupted()三者的区别
interrupt()是给当前线程添加中断标志位,但是不影响该线程的状态。
interrupted()是判断 当前 线程是否为中断状态。并且删除中断标志位(注意 当前!在main方法中写thread对象.interrupted时这个时候指代的是main线程)所以必须要写为 Thread.currentThread.interrupt(),建议写在单独的线程里)
Isinterrupt(是判断当前线程是否为中断状态 中断为true 非中断为 false)
import threadtest.ThreadText;
public class ThreadTest extends Thread {
public void run(){
for(int i=0;i<10;i++){
System.out.println(Thread.currentThread().getName()+i);
//isInterrupted() 检测该线程是否中断 中断:true 非中断:false
//不修改中断的状态
if(this.isInterrupted()){
//interrupted 检测线程是否中断,中断为true 非中断false 使用后将删除中断标志位
System.out.println(this.interrupted());//true
System.out.println(this.interrupted());//false
break;
}
}
}
public static void main(String[]args){
ThreadTest threadText=new ThreadTest();
threadText.start();
//设置中断
threadText.interrupt();
}
}
线程的状态:
New(新创建):用new操作符创建新的线程,该线程还未运行,程序中没有开始运行线程的代码,在线程运行的过程中还有一些基础的工作需要做。
Runnable(可运行):调用start()方法线程处于runnable状态,这个线程在这个状态可能正在运行,也可能没有运行,这取决于操作系统给线程提供的运行时间,事实上,这个线程被中断,目的是为了让其他的线程获得运行的机会,抢占式调度系统给每一个可以运行的线程一个时间片来执行任务,当时间片用完后,操作系统剥夺该线程的运行权利,给另一个线程一个运行的机会,当系统选用线程时,也是在考虑线程的优先级别的。
Block(阻塞)、Waiting(等待) :当一个线程进入阻塞或者等待状态的时候,暂时不活动,它不运行任何代码并且消耗最少的资源,知道线程调度器重新激活他们,进入这两种状态有两个原因 1)当一个线程视图获取一个内部锁的对象,但是这个锁目前被其他线程所持有,这个时候线程进入阻塞的状态,当其他线程将这个锁进行了释放,该线程又变成非阻塞状态了。
2)当该线程等待另一个线程通知调度器一个条件时,它自己进入等待状态,调用wait方法或者Thread.join方法,或者库中的Lock或者Condition时会出现这种情况
Terminated(被终止):线程终止无非就2个原因:1)因为run方法正常退出而自然死亡。2)因为一个没有捕获的异常终止了run方法,而导致自然死亡。
线程的 join()方法和 getState()还有stop()方法
join()是指定等待该调用者线程:调用者没有执行完,其他线程不许走!
join(时间) 是指等待该调用者线程多少时间,等到这个时间结束了,其他线程按照优先级随机运行线程。
getState()得到调用者线程的状态
stop()停止该线程
suspend()暂停这一线程的执行,过时
resume() 当用suspend线程暂停后可以用该方法会发该线程。
锁对象
多个线程访问共享资源
解决方案: 同步锁
隐式锁
(1)同步代码块 (灵活) ,因为它的同步监视可以是任何对象
(2)同步方法 同步监视器只能是当前对象this