hooyantsing's Blog

第90次课程_线程

字数统计: 1.1k阅读时长: 5 min
2019/12/10

源辰76班

第90次课程

2019.12.10

内容

线程[廖彦]

1.创建线程的方式

1.继承Thread类

2.实现Runnable接口

Demo.java

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
package com.yc.thread;
public class Demo {
    public static void main(String[] args) {
       /**
        * 线程创建方式:
        * 1.继承Thread类
        * 2.实现Runnable接口
        */
       Thread t1 = new MyThread1();
       //优先级    10最高  0最低
       t1.setPriority(10);
       t1.start();
       
       Runnable r1 = new MyRunnable2();
       Thread t2 = new Thread(r1);
       t2.setPriority(10);
       t2.start();
    }
    
    public void demo() throws  InterruptedException {
       Thread t = Thread.currentThread(); //返回当前线程
       
       //实例方法
       t.getId(); //唯一标识
       t.getName(); //名称
       t.getPriority(); //优先级
       t.getState(); //状态
       t.getThreadGroup(); //线程组
       t.isAlive(); //判断线程是否处于活动状态
       t.isDaemon(); //判断线程是否是精灵线程
       t.isInterrupted(); //判断线程是否处于中断状态
       
       //静态方法
       Thread.currentThread(); //返回当前线程对象
       Thread.sleep(2000); //线程休眠
       Thread.yield(); //让渡/屈服
       
       t.join(); //加入
       t.run(); //逻辑代码
       t.start(); //启动线程
       
    }
    
}
class MyThread1 extends Thread {
    @Override
    public void run() {
       for(int i=0;i<100;i++) {
           System.out.println("听歌" + i);
           /*try {
               Thread.sleep(20);
           } catch (InterruptedException e)  {
               e.printStackTrace();
           }*/
       }
    }
    
}
class MyRunnable2 implements Runnable{
    @Override
    public void run() {
       for(int i=0;i<100;i++) {
           System.out.println("玩游戏" + i);
           /*try {
               Thread.sleep(20);
           } catch (InterruptedException e)  {
               e.printStackTrace();
           }*/
       }
    }
    
}

**2.**匿名类创建线程/join()方法阻塞线程

Demo1.java

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
package com.yc.thread;
public class Demo1 {
    public static void main(String[] args) {
       
       /*使用匿名类创建线程*/
       Thread t1 = new Thread("看书") {
           @Override
           public void run() {
               for(int i=0;i<100;i++) {
                  System.out.println(Thread.currentThread().getName() + i);
                  try {
                      Thread.sleep(20);
                  } catch  (InterruptedException e) {
                      e.printStackTrace();
                  }
               }
           }
       };
       
       Thread t2 = new Thread("听歌") {
           @Override
           public void run() {
               for(int i=0;i<100;i++) {
                  if(i==50) {
                      try {
                          //t2线程阻塞,持续到t1线程结束
                          t1.join();
                      } catch  (InterruptedException e) {
                          e.printStackTrace();
                      }
                  }
                  System.out.println(Thread.currentThread().getName() + i);
                  try {
                      Thread.sleep(20);
                  } catch  (InterruptedException e) {
                      e.printStackTrace();
                  }
               }
           }
       };
       
       t1.start();
       t2.start();
    }
}

3.线程分类

1.父线程:默认情况下,父线程会等到所有子线程执行完才结束,尽管主线程代码已经执行完,主线程仍会等待。

2.子线程

2.精灵线程/守护线程:当父线程执行完毕时,无论精灵线程/守护线程是否执行完毕,都将其直接结束(咔嚓)。

Demo2.java

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
package com.yc.thread;
public class Demo2 {
    /*
     * 线程分类:
     * 1.父线程 默认情况下,父线程会等到所有子线程执行完才结束,尽管主线程代码已经执行完,主线程仍会等待
     * 2.子线程
     * 2.精灵线程/守护线程 setDaemon(true)必须在启动前设置好
     */
    public static void main(String[] args) {
       //main方法本身就是一个线程,为父线程
       //在此方法之下创建的线程,为子线程

       Thread t1 = new Thread("精灵线程/守护线程") {
           @Override
           public void run() {
               for(int i=0;i<100;i++) {
                  System.out.println(Thread.currentThread().getName() + i);
                  try {
                      Thread.sleep(50);
                  } catch  (InterruptedException e) {
                      e.printStackTrace();
                  }
               }
           }
       };
       //设置为守护线程 true
       t1.setDaemon(true);
       t1.start();
       
       for(int i=0;i<100;i++) {
           System.out.println(Thread.currentThread().getName() + i);
           try {
               Thread.sleep(20);
           } catch (InterruptedException e)  {
               e.printStackTrace();
           }
       }
       
       System.out.println("主程序的代码已经执行完毕");
    }
}

**4.资源竞争问题/**synchronized同步关键字

synchronized

加入关键字后,逻辑代码每次仅允许一个线程执行。解决了资源竞争问题。

加在方法上

1
2
3
public synchronized Object functionName() {
    //more code ...
}

加在代码块上

1
2
3
synchronized (this) {
   //more code ...
}

Demo3.java

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
package com.yc.thread;
import java.util.ArrayList;
public class Demo3 {
    
    ArrayList<Object> list = new  ArrayList<Object>();
    
    public Demo3() {
       for(int i=0;i<100;i++) {
           list.add(i);
       }
    }
    
    /**
     * synchronized 同步关键字
     * 1.加在方法之上
     *     实例方法加synchronized 会锁定 当前对象(this)
     *     静态方法加synchronized 会锁定 当前类(class)
     * 2.加在代码块上
     */

    //public synchronized Object  synchronizedgetObj() throws  InterruptedException {
    public Object getObj() throws  InterruptedException {
       //(对象名) 填写被竞争资源名或包含其的父类名
       //synchronized (list)
       synchronized (this) {
           //资源竞争
           if(list.size()>0) {
               Thread.sleep(10);
               return list.remove(0);
           }
       }
       return null;
    }
    public static void main(String[] args) {
       Demo3 demo3 = new Demo3();
       
       MyThread t1 = new MyThread(demo3);
       MyThread t2 = new MyThread(demo3);
       MyThread t3 = new MyThread(demo3);
       MyThread t4 = new MyThread(demo3);
       t1.start();
       t2.start();
       t3.start();
       t4.start();
    }
}
class MyThread extends Thread{
    private Demo3 demo3;
    public MyThread(Demo3 demo3) {
       this.demo3 = demo3;
    }
    
    public void run() {
       Object obj;
       try {
           while((obj=demo3.getObj())!=null)  {
               System.out.println(Thread.currentThread().getName()+"获取了元素:"+obj);
           }
       } catch (InterruptedException e) {
           e.printStackTrace();
       }
    }
}
CATALOG