Java多线程基础简介

1.线程与进程
进程是系统进行资源分配和调度的一个独立单位,而线程是进程中独立运行的子任务。多线程是异步的,CPU可以在执行各个任务间来回切换执行,使系统的运行效率大大的提升。
2.java实现多线程的方法
1)继承Thread类
书写线程类继承Thread类,重写Thread类中的run()方法,通过.start()方法来启动线程,启动线程后,run方法等待被调用。run方法的执行与start()方法执行顺序无关,如果直接调用run方法,则为正常的方法调用,并不是线程。
注:如果多次调用start方法,会抛出IllegalThreadStateException异常。
2)实现Runnalble接口
实现Runnalble接口,实现run方法,启动线程的方式如下:

Thread newThread = new Thread(Runnalble runnalble);
newThread.strat() ;

3.线程安全
在多个线程对实例变量进行操作时,会发生值被改变、值不同步的情况,进而程序的执行流程。如:

class MyThread extends Thread{
private int  count=5 ;
public MyThread(String name) {
    super() ;
    this.setName(name);
}
@Override
public void run(){
    count++ ;
        System.out.println(this.currentThread().getName()+count) ;
    }
}

不共享数据的调用:

MyThread a = new MyThread("A") ;
MyThread b = new MyThread("B") ;
MyThread c = new MyThread("C") ;
a.start() ;
b.start() ;
c.start() ;
结果:
A6
C6
B6

输出结果那个线程先执行run方法是随机的。
共享数据:

MyThread ccc = new MyThread("ccc") ;
Thread a = new Thread(ccc,"A") ;
Thread b = new Thread(ccc,"B") ;
Thread c = new Thread(ccc,"C") ;
a.start();
b.start();
c.start();
结果:
A7
C8
B7

造成原因:jvm执行的是先取的count值,然后计算count+1,最后对count赋值,AB线程都在都count赋值前在两个线程对count+1操作已经执行完成,值为7的时候才执行了赋值操作,造成两个为7.
解决方法:
1)在run方法前加synchronized关键字

synchronized public void run(){
    count++ ;
    System.out.println(this.currentThread().getName()+count) ;
}

2)将run方法的执行书写成同步代码块

public void run(){
    synchronized (this) {
        count++ ;
        System.out.println(this.currentThread().getName()+count) ;
    }
}

加synchronized关键字,使多线程执行run方法时或同步代码块时,以等待的方式进行处理。
注:System.out.println(x)方法内部是同步的,源码为:

synchronized(this){
print(x) ;
newLine()
}

4.常用方法
1)currentThread()方法:返回代码段正在被哪个线程调用的信息,使用方法:

Thread.currentThread();//返回Thread

2)isAlive()方法:判断当前线程是否处于活动状态,即:线程已经启动且没有执行完成。
3)sleep(long l)方法:使当前正在执行的线程休眠,l为休眠的毫秒数,休眠的线程是Thread.currentThread() ;休眠方法:

Thread.sleep(1000);//休眠一秒

4)getId()方法:获取线程的唯一标示。
5)yield()方法:放弃当前CPU资源,不一定立即放弃。
6)setPriority()方法:设置线程的优先级,优先级的等级为1-10,线程优先级高的不一定会先执行完。其中线程优先级有继承性,A启动B线程,则B线程的优先级与A线程一致。
5.停止线程
1)stop()方法:立即停止线程,立即释放锁,导致数据得不到同步处理,造成数据不一致的问题,该方法为作废的方法。
2)interrupt()方法:添加一个中止的标志,并未真正的终止中程。
3)interrupted():测试线程是否中止,会清除状态,两次调用会返回false ;isInterrupted():测试线程是否中止,不会清除状态。
4)使用interrupt和retrun做到中止线程的功能,在线程类中判断线程是否中止this.*,中止return即可。
5)线程处于sleep状态调用interrupt方法会跑异常,并且清除状态,当调用interrupt遇到sleep同样会抛出异常。
6.暂停线程
1)suspen()方法:暂定线程。
2)resume()方法:恢复线程。
暂定线程会出现于stop相同的问题,这两个方法都为作废的方法。

猜你喜欢

转载自blog.csdn.net/qq_36831305/article/details/82417322