概要:

一:线程状态

(1)新生状态-》创建线程对象然后实现start()方法
(2)就绪状态
(3)运行状态-》cpu调度
(4)阻塞状态
(5)死亡状态

二:停止线程

1.自然终止:线程体正常运行完毕
2.外部干涉:
1)线程类中定义线程体的标识
2)线程体使用该标识
3)提供对外的方法改变该标识
4)外部根据条件调用该方法即可

三:阻塞

1.join:合并线程,Y.join(),则先执行Y对象里面的线程体
2.Thread.yield():暂停线程,当前的方法体
3.Thread.sleep():睡眠,模拟延时,但有可能出现数据异常,资源冲突

四:线程基本信息

 isAlive():判断线程是否活着,是否未终止
 getPriority():获取线程的优先级数据,优先级代表的是概率,并非绝对的先后顺序
 setPriority():设置线程的优先级
 setName():给线程取名字
 getName():获取线程名字
 currentThread():获取当前正在运行的线程对象,也就是取得自己本身

五:线程同步(线程并发)

 synchronized->同步
 (1)同步块:
 synchronized(引用类型 || this || 类.class){}
 (2)同步方法:
 synchronized 方法名(){}
 
  多个线程访问同一份资源,确保资源安全->线程安全
  线程安全则效率低,反之

 

SRE实战 互联网时代守护先锋,助力企业售后服务体系运筹帷幄!一键直达领取阿里云限量特价优惠。

六:死锁

 

①、互斥条件:资源不能被共享,只能被同一个进程使用;

②、请求与保持条件:已经得到资源的进程可以申请新的资源;

③、非剥夺条件:已经分配的资源不能从相应的进程中强制剥夺;

④、循环等待条件:系统中若干进程形成环路,该环路中每个进程都在等待相邻进程占用的资源。

过多的同步可能造成死锁-->利用生产者消费者模式解决死锁问题

 

上代码了解一下:

(简单利用静态代理模式)

1.具体角色:

 

 1 package com.test;
 2 /*使用Runnable创建线程
 3  * 1.使用静态代理模式实现启动多线程
 4  * (1)创建真实角色
 5  * (2)创建代理角色
 6 */
 7 public  class Singer implements Runnable {
 8 
 9     @Override
10     public void run() {
11         System.out.println("歌手线程执行->歌手曹操准备上台唱歌。。");
12     }
13 }

 

2.代理角色:保持对具体角色的引用

 1 package com.test;
 2 
 3 public class Agent implements Runnable{
 4     Singer singer=new Singer();
 5     Thread t1=new Thread(singer);
 6     public Agent(Singer singer) {
 7         super();
 8         this.singer = singer;
 9     }
10     private void before() {
11         System.out.println("代理员线程执行->代理员已经准备好台前工作,歌手就绪!");
12     }
13     private void after() {
14         System.out.println("代理员线程执行->代理员已经收拾完场地,护送歌手离开!");
15     }
16 
17     @Override
18     public void run() {
19         System.out.println("歌手线程未启动:"+t1.isAlive());
20         before();
21         t1.start();    
22         t1.setName("歌手线程");
23         System.out.println("当前线程为:"+t1.currentThread());
24         System.out.println("当前线程名称:"+t1.getName());
25         System.out.println("歌手线程启动:"+t1.isAlive());
26         //这里存在多线程运行的延时,即代理员的线程可能运行在歌手的线程前面
27         after();
28     }
29 }

3.场景模拟:

 1 package com.test;
 2 /*
 3  * 场景模拟:实现多线程的启动
 4  */
 5 public class Client {
 6 
 7     public static void main(String[] args) throws InterruptedException {
 8         //具体角色
 9         Singer singer=new Singer();
10         //代理角色
11         Agent ag=new Agent(singer);
12         Thread p2=new Thread(ag);
13         //启动线程
14         p2.start();
15     }
16 }

效果截图:

java-初识多线程 随笔 第1张

 利用生产者消费者模式解决死锁问题:

1.共享资源

 

 1 package com.deadclock;
 2 //共享资源
 3 public class Movie {
 4     private String pic;
 5     //定义一个信号灯,用于标识生产者消费者的处理结果,以及通知顺序
 6     private boolean flag=true;
 7 
 8     //加入同步锁防止资源分配不当出现死锁
 9     public  synchronized void play(String pic) {
10         
11         if(!flag) {//生产者等待
12             try {
13                 this.wait();
14             } catch (InterruptedException e) {
15                 e.printStackTrace();
16             }
17         }
18         //开始生产
19         try {
20             Thread.sleep(500);
21         } catch (InterruptedException e) {
22 
23             e.printStackTrace();
24         }
25         //生产完毕
26         this.pic=pic;
27         //通知消费者
28         this.notify();
29         this.flag=false;
30     }
31 
32     public synchronized void watch() {
33         if(flag) {//消费者等待
34             try {
35                 this.wait();
36             } catch (InterruptedException e) {
37                 e.printStackTrace();
38             }
39             //开始消费
40             try {
41                 Thread.sleep(200);
42             } catch (InterruptedException e) {
43                 e.printStackTrace();
44             }
45         }
46         //消费完毕
47         System.out.println(pic);
48         //通知生产者
49         this.notify();
50         this.flag=true;
51     }
52 
53 }

 

2.具体访问共享资源角色:

 1 package com.deadclock;
 2 //使用共享资源的具体角色
 3 public class Player implements Runnable{
 4     
 5     private Movie m;
 6     
 7     //构造器,传入movie对象
 8     public Player(Movie m) {
 9         super();
10         this.m=m;
11     }
12     
13     @Override
14     public void run() {
15         
16         for(int i=0;i<=10;i++) {
17             if(i%2==1) {
18                 m.play("奇数"+i);
19             }
20             else 
21                 m.play("偶数"+i);
22         }
23     }
24 }
 1 package com.deadclock;
 2 //使用共享资源的具体角色
 3 public class Watcher implements Runnable{
 4 
 5     private Movie m;
 6     
 7     //构造器,传入movie对象
 8     public Watcher(Movie m) {
 9         super();
10         this.m=m;
11     }
12     
13     @Override
14     public void run() {
15         for(int i=0;i<=10;i++) {
16             m.watch();
17         }
18     }
19 }

3.场景模拟

 1 package com.deadclock;
 2 
 3 public class Client {
 4 
 5     public static void main(String[] args) {
 6         //共享资源初始化
 7         Movie m=new Movie();
 8         //具体使用资源对象
 9         Player p=new Player(m);
10         Watcher w=new Watcher(m);
11         //创建线程
12         Thread t1=new Thread(p);
13         Thread t2=new Thread(w);
14         //开启线程
15         t1.start();
16         t2.start();
17     }
18 
19 }

效果截图:

java-初识多线程 随笔 第2张

 

 

简单练习一下利用面向对象编程:

场景模拟,使用多线程描述代驾员帮忙代驾的场景
  1.首先司机到达代驾员处
  2.正式会面
  3.然后开始任务交接
  4.结束

1.具体的驾驶员角色

 

 1 package com.oob;
 2 //具体角色->驾驶者
 3 public class Driver implements Runnable{
 4     //驾驶员的名字和车
 5     private String dName;
 6     private String car;
 7     
 8     public String getdName() {
 9         return dName;
10     }
11     public void setdName(String dName) {
12         this.dName = dName;
13     }
14     public String getCar() {
15         return car;
16     }
17     public void setCar(String car) {
18         this.car = car;
19     }
20 
21     @Override
22     public String toString() {
23         return "驾驶者线程-->>驾驶者"+dName+"已将"+car+"开往代驾员所在位置!";
24     }
25     //构造方法
26     public Driver(String dName, String car) {
27         super();
28         this.dName = dName;
29         this.car = car;
30     }
31     public Driver() {
32 
33     }
34     @Override
35     public void run() {
36         Driver d=new Driver("小王","奔驰");
37         System.out.println(d.toString());
38     }
39 }

 

2.代理角色

 1 package com.oob;
 2 //代理角色,代驾
 3 public class DriverProxy implements Runnable{
 4     //代驾员的名字,代驾起点,终点
 5     private String pName;
 6     private String start;
 7     private String last;
 8     
 9     public String getpName() {
10         return pName;
11     }
12 
13     public void setpName(String pName) {
14         this.pName = pName;
15     }
16 
17     public String getStart() {
18         return start;
19     }
20 
21     public void setStart(String start) {
22         this.start = start;
23     }
24 
25     public String getLast() {
26         return last;
27     }
28 
29     public void setLast(String last) {
30         this.last = last;
31     }
32 
33     public DriverProxy(String pName, String start, String last) {
34         super();
35         this.pName = pName;
36         this.start = start;
37         this.last = last;
38     }
39 
40     public DriverProxy() {
41         super();
42     }
43     
44     @Override
45     public String toString() {
46         return "代驾员线程-->>代驾员"+pName+"正开着客户的车从"+start+"出发前往"+last+"!";
47     }
48 
49     @Override
50     public void run() {
51         Driver d=new Driver("小王","奔驰");
52         DriverProxy p=new DriverProxy("小张","锦绣花园","万达广场");
53         System.out.println("代驾员线程-->>代驾员"+p.getpName()+"与客户"+d.getdName()+"成功会面!");
54         System.out.println(p.toString());
55         System.out.println("代驾员线程-->>代驾员"+p.getpName()+"与客户"+d.getdName()+"分开,并将"+d.getCar()+"归还!");
56         
57     }
58 
59 }

3.场景模拟

 1 package com.oob;
 2 /*场景模拟,使用多线程描述代驾员帮忙代驾的场景
 3   1.首先司机到达代驾员处
 4   2.正式会面
 5   3.然后开始任务交接
 6   4.结束
 7 */
 8 public class Client {
 9 
10     public static void main(String[] args) {
11         //具体角色
12         Driver d=new Driver();
13         Thread t1=new Thread(d);
14         t1.start();
15         //代理者角色
16         DriverProxy p=new DriverProxy();
17         Thread t2=new Thread(p);
18         //启动线程    -->由此可以看出当线程启动后具体角色以及代理者角色均被初始化导致数据为空
19         t2.start();
20     }
21 }

效果截图:

java-初识多线程 随笔 第3张

 

 

ps:文章仅作学习了解,如有不对之处欢迎大佬指正。

 

扫码关注我们
微信号:SRE实战
拒绝背锅 运筹帷幄