corejava学习-----------------线程

一、线程的作用

    (1)做一个非常耗时间的代码,线程执行循环读写操作
    (2)使用线程让多个代码同时执行,视频下载

 

二、线程的分类

    (1)前台线程(执行线程)
             自己执行,自己停止
    (2)后台线程(守护线程/精灵线程)
             该线程不会单独执行, 当其他非守护线程都执行结束后, 自动退出【守护线程 也可以守护 main线程】

 

三、如何编写一个线程

(1)继承Thread类
        写一个普通类继承Thread类,重写run()方法
        使用:通过new一个Thread的实例,调用start方法让这个线程进入就绪状态

Thread t = new MyThread();
t.start();

(2)实现Runnable接口
        写一个普通类实现Runnable类,实现run()方法
        使用:

Ruunable r = new MyRunnable();
Thread t = new Thread(r);
t.start();

四、线程的生命周期

    生命周期图
         corejava学习-----------------线程_第1张图片

线程的五种状态
    corejava学习-----------------线程_第2张图片

 

 

五、Thread类中常用的方法

  •     start()方法

        (1)实例方法
        (2)启动线程,线程只能启动一次

  •     currentThread()方法

        (1)是一个静态方法,可通过类名直接调用
        (2)获取当前正在运行的线程

  •     getName()/setName()方法

        (1)实例方法
        (2)给调用该方法的线程获取或者设置名字

  •     sleep()方法

        (1)是一个静态本地方法,这个方法的特点就是可以通过实例/类名来调用
        (2)调用sleep()方法的线程,会让出CPU进入阻塞状态,结束睡眠之后,进入就绪状态,sleep()睡眠时保持对象锁。

  •     yield()方法

        (1)是一个静态本地方法,这个方法的特点就是可以通过实例/类名来调用
        (2)调用yield()方法的线程会让出CPU给那些优先级比我的当前线程高或者同级的线程去使用(建议性的),调用这个方法的线程会进入就绪状态,再次去争取CPU的使用权,调用yield()方法并不会释放对象锁,

  •     join()方法

        (1)实例方法
        (2)有线程t1和t2,在线程t1中调用t2.join()方法表示:t1线程进入阻塞状态->等待t2线程执行完,->再次进入就绪态

  •     setPriority(int)

        (1)实例方法
        (2)setPriority(int)设置线程的优先级,优先级取值 1 到 10,参数越大优先级越高。建议性的

  •     interrupt()和isInterrupt()和interrupted()

        (1)实例方法
        (2)interrupt();设置线程中断的状态,但是不会真正的中断-->中断状态为true
                 isInterrupted();获得标志位,判断自己是否被人中断了,如果有人要中断我,我就自己中断一下我自己,但是不会清空标志位
                 interrupted();获得标志位,会清空标志位

  •     stop()

        (1)实例方法
        强制终止一个线程

  •     setDaemon()

        (1)实例方法
        该线程不会单独执行, 当其他非守护线程都执行结束后, 自动退出【守护线程 也可以守护 main线程】
    

拓展

一、wait()方法和sleep()方法的区别

        1、Object类中的wait()方法
                (1)wait()方法是Object类中的方法,当线程执行到wait()方法时,它就进入到一个和该对象相关的等待池中,同时释放对象的机锁(暂时失去机锁,wait(long tiomeout)超过时间后还需返回对象锁);其他线程可以访问
                (2)wait()使用notify或者notifyAll或者指定睡眠时间唤醒当前等待池中的线程。
                (3)wait()必须放在synchronized block中。
                (4)必须确保wait()在notify()/notifyAll()之前,不然会产生永远死锁的状态
        2、Thread类中sleep()方法
                调用sleep()方法的线程,会让出CPU进入阻塞状态,结束睡眠之后,进入就绪状态,sleep()睡眠时保持对象锁。

二、释放锁对象和不释放锁对象的情况:

        1、释放对象锁
            执行完同步代码块;
            执行同步代码块过程中,遇到异常而导致线程终止,释放锁;
            执行同步代码块过程中,执行了锁所属对象的wait()方法,释放锁进入对象的等待池;


        2、不释放对象锁的方法
            Thread.sleep()方法,放弃CPU,进入阻塞状态;
            Thread.yield()方法,放弃CPU,进入就绪状态;
            suspend()方法,暂停当前线程,已废弃;

 

六、线程编程

    线程同步编程(synchronized关键字)
    1、为什么要使用同步机制
            当多个线程去操作同一个数据时可能会出现数据混乱的问题,如何处理??  ==》同步原理
           1.同步方法:
              (1)普通成员方法:synchronized 修饰的方法      ex:public synchronized void test(){}    
                   共享对象,默认是this(也就是当前类对象)
              (2)静态成员方法:static synchronized  修饰的方法  ex:public static synchronized void test() {}
                  共享对象,默认是类的.class对象(也就是类的字节码对象)
           2.同步代码块:
              synchronized(共享对象){}
         弊端:方法中的所有代码,都只允许一个线程访问。

    2、编程步骤
        (1)找到同步线程的共享对象
            什么样的对象可以用作共享对象呢?
                一般是共享的,并且只有一个的对象,比如:字节码对象、this、static修饰的对象、常量等等
        (2)确定临界区:哪些代码在操作公有data
        (3)在临界区上方用synchronized来拿一个共享对象的锁,临界区的下方会用 } 释放锁


    线程间通信编程编程步骤
        (1)找到同步线程的共享对象
        (2)站到线程内部分析:每个线程单独分析,需要wait()还是notify()
        (3)控制wait()发生在notify()之前:无固定模式


    线程的死锁
        A线程等待B线程持有的锁,B线程等待A线程持有的锁

public class DeadLockThreadTest {
	private static String str1 = "筷子1";
	private static String str2 = "筷子2";

	public static void main(String[] args) {
		// 使用匿名内部类的方式,继承Thread这个父类
		new Thread() {
			public void run() {
				while (true) {
					synchronized (str1) {
						System.out.println(getName() + "拿到了" + str1 + "\t等待" + str2);
						synchronized (str2) {
							System.out.println(getName() + "拿到了"+ str2 + "开吃");
						}
					}
				}
			}
		}.start();
		new Thread() {
			public void run() {
				while(true) {
					synchronized (str2) {
						System.out.println(getName() + "拿到了" + str2 + "\t等待" + str1);
						synchronized (str1) {
							System.out.println(getName() + "拿到了" + str1 + "开吃");
						}
					}
				}
			}
		}.start();
	}
}

 

你可能感兴趣的:(线程,corejava,线程,corejava)