进程:系统进行资源分配和调度的一个独立单位
线程:在进程中独立运行的子任务
线程启动顺序与start()执行顺序无关
非线程安全:指多个线程对同一个对象中的同一个实例变量进行操作时会出现值被更改、值不同步的情况,进而影响程序的执行流程。
解决方法:在run方法前加入synchronized关键字,使多个线程在执行run方法时,以排队的方式进行处理
public class MyThread extends Thread{
private int count = 5;
@Override
synchronized public void run(){
super.run();
count--;
System.out.println("由"+this.currentThread().getName()+" 计算,count="+count);
}
}
在Java中有三种方法可以终止正在运行的线程:
判断线程是否是停止状态,Thread类中有以下两个方法:
suspend()方法暂停线程,resume()方法恢复线程的执行
缺点:
yield()方法的作用是放弃当前的CPU资源,将它让给其他的任务去占用CPU执行时间,但放弃的时间不确定,有可能刚刚放弃,马上又获取CPU时间片
在Java线程中有两种线程,一种是用户线程,另一种是守护线程
守护线程是一种特殊的线程,它的特性有”陪伴”的含义,当进程中不存在非守护线程了,则守护线程自动销毁。典型的守护线程就是垃圾回收线程
用关键字synchronized声明方法在某些情况下是有弊端的,比如A线程调用同步方法执行一个长时间的任务,那么B线程必须等待比较长的时间
synchronized同步代码块的使用:当两个并发线程访问同一个对象object中的synchronized(this)同步代码块时,一段时间内只能有一个线程被执行,另一个线程必须等待当前线程执行完这个代码块以后才能执行该代码块。
即为在synchronized块中就是同步执行,不在synchronized块中就是异步执行,这样可以提高运行效率
在使用synchronized(this)代码块时需要注意的是,当一个线程访问object的一个synchronized(this)同步代码块时,其他线程对同一个object中所有其他synchronized(this)同步代码块的访问将被阻塞,这说明synchronized使用的”对象监视器”是一个
同步synchronized(this)代码块是锁定当前对象的
除了使用synchronized(this)格式来同步代码块外,Java还支持对”任意对象”作为”对象监视器”来实现同步功能,这个”任意对象”大多数是实例变量及方法的参数,使用格式为synchronized(非this对象x)
关键字synchronized还可以应用在static静态方法上,相当于对当前*.java文件对应的Class类进行持锁,Class锁可以对类的所有对象实例起作用
同步synchronized(class)代码块的作用和synchronized static方法的作用一样
死锁:不同的线程都在等待根本不可能被释放的锁,从而导致所有的任务都无法继续完成
当多个线程同时持有锁对象时,如果持有的是相同的锁对象,这些线程之间就是同步的,否则就是异步的
主要作用是使变量在多个线程间可见,关键字volatile强制从公共堆栈中取得变量的值,而不是从线程私有数据栈中取得变量的值
public class RunThread extends Thread {
volatile private boolean isRunning = true;
public boolean isRunning(){
return isRunning;
}
public void setRunning(boolean isRunning){
this.isRunning = isRunning;
}
@Override
public void run(){
System.out.println("进入run了");
while(isRunning == true){
}
System.out.println("线程被停止了!");
}
}
public class Run {
public static void main(String[] args){
try{
RunThread thread = new RunThread();
thread.start();
Thread.sleep(1000);
thread.setRunning(false);
System.out.println("已经赋值为false");
}catch(InterruptedException e){
e.printStackTrace();
}
}
}
volatile具有非原子的特性,可能导致线程不安全,可以用synchronized关键字实现同步或使用AtomicInteger原子类进行实现
private AtomicInteger count = new AtomicInteger(0);
...
count.incrementAndGet();//自增1
关键字synchronized可以使多个线程访问同一个资源具有同步性,而且它还具有将线程工作内存中的私有变量与公共内存中的变量同步的功能