一、线程:
并发,OS将时间分成若干段,并分配给每个进程或线程,得到时间片段的进程或线程将得到cpu的执行,微观上进程或线程是走走停停,宏观上是同时在执行,这种现象称为并发。
同步,不同的进程或线程对数据操作时,只能在一个完成后另外一个才能开始操作。
异步,不同的进程或线程对数据操作在宏观上是同时对其操作的,这种情况可能会有安全问题。
线程,一个进程中可能会包含很多的进程,每一个线程可以单独完成一个简单的任务,但是线程是不能独立存在和运行的,它们需要共享进程的内存空间。
一个进程最少会有一个调用main方法的线程,所有的线程都可以互不干扰的运行,只有所有的线程都执行完毕或者出错停止以后进程才真正的结束。
二、创建一个线程:
Thread类,一个Thread类的实例就是一个具体的线程,我们可以继承于Thread并且重写其中的run方法来实现我们具体操作。
class className extends Thread{
public void run(){}
}
Thread t1 = new className();
t1.start();//注意不要调用run方法,因为那样的话就无法实现线程的并发运行。调用start方法后,程序会尽快调用线程的run方法。
不过我们一般不建议使用上面的方法来声明一个线程,而应该是将线程体和线程的启动分开,这时线程应实现Runnable接口,然后实现其中的run方法:
class className implements Runnable{//线程体
public void run(){}
}
Runnable runnable = new className();//线程实例化
Thread t1 = new Thread(runnable);
t1.start();
或者我们可以简单的使用匿名内部类的方式:
Thread t1 = new Thread(new Runnable(){
public void run(){}
});
三、线程一些方法:
static void yield();主动放弃当前时间片段的执行。
static void sleep(long time);从running状态主动进入block状态,阻塞time毫秒后,自动回到runnable状态。
void interrupt():中断线程,若在阻塞过程中被打断,阻塞会引发异常:InterruptException。
四、线程的优先级:
线程的优先级高的线程,被分配时间片段的几率高,也就被cpu执行的次数多,这都是相对的,并不是绝对的,在大多数情况下是这样的。线程优先级根据数字划分为10个等级:1最小对应Thread常量MIN_PRIORITY;10最大对应Thread常量MAX_PRIORITY;默认为5,对应Thread常量NORM_PRIORITY
public final void setPriority(int newPriority);
五、守护线程(后台线程):
守护线程的特点是:当线程中所有前台线程都终止后,守护线程自动强制终止,这个时候进程也终止。
后台线程是在线程启动前通过方法设置的,必须是在start()方法之前设置才有效。 setDaemon(boolean on),当参数是true时,该线程为后台线程。
六、线程安全问题:
当多线程异步共享同一数据时,就有可能引发线程安全问题。解决办法就是将异步访问变成同步访问,使用synchronized关键字实现。synchronized关键字可以修饰方法也可以修饰一个代码块。
synchronized修饰方法时,一个线程进入该方法后,会对该方法所属的对象加锁,那么其他线程访问该对象时,发现该对象被上锁就只能在外等待直到锁被释放。
synchronized修饰代码块格式是:
synchronized(Object obj){...},其中的obj可以是任意的对象,synchronized就是给这个对象加锁以实现同步访问代码块,所以就一定要注意不同的比较的这个obj是同一个对象。