线程(一)

1。单进程单线程:一个人在一个桌子上吃菜。
2。单进程多线程:多个人在同一个桌子上一起吃菜。
3。多进程单线程:多个人每个人在自己的桌子上吃菜。

多线程的问题是多个人同时吃一道菜的时候容易发生争抢,例如两个人同时夹一个菜,一个人刚伸出筷子,结果伸到的时候已经被夹走菜了。。。此时就必须等一个人夹一口之后,在还给另外一个人夹菜,也就是说资源共享就会发生冲突争抢。

https://blog.csdn.net/function__/article/details/80883084
多线程死锁的产生以及如何避免死锁
多线程以及多进程改善了系统资源的利用率并提高了系统 的处理能力。然而,并发执行也带来了新的问题——死锁。所谓死锁是指多个线程因竞争资源而造成的一种僵局(互相等待),若无外力作用,这些进程都将无法向前推进。

下面我们通过一些实例来说明死锁现象。

先看生活中的一个实例,2个人一起吃饭但是只有一双筷子,2人轮流吃(同时拥有2只筷子才能吃)。某一个时候,一个拿了左筷子,一人拿了右筷子,2个人都同时占用一个资源,等待另一个资源,这个时候甲在等待乙吃完并释放它占有的筷子,同理,乙也在等待甲吃完并释放它占有的筷子,这样就陷入了一个死循环,谁也无法继续吃饭。。。

二、死锁产生的原因
1) 系统资源的竞争

通常系统中拥有的不可剥夺资源,其数量不足以满足多个进程运行的需要,使得进程在 运行过程中,会因争夺资源而陷入僵局。只有对不可剥夺资源的竞争 才可能产生死锁,对可剥夺资源的竞争是不会引起死锁的。

2) 进程推进顺序非法

进程在运行过程中,请求和释放资源的顺序不当,也同样会导致死锁。例如,并发进程 P1、P2分别保持了资源R1、R2,而进程P1申请资源R2,进程P2申请资源R1时,两者都 会因为所需资源被占用而阻塞。

信号量使用不当也会造成死锁。进程间彼此相互等待对方发来的消息,结果也会使得这 些进程间无法继续向前推进。例如,进程A等待进程B发的消息,进程B又在等待进程A 发的消息,可以看出进程A和B不是因为竞争同一资源,而是在等待对方的资源导致死锁

3) 死锁产生的必要条件
产生锁必须同时满足以下四个条件,只要其中任一条件不成立,死锁就不会发生。
互斥条件:进程要求对所分配的资源(如打印机)进行排他性控制,即在一段时间内某 资源仅为一个进程所占有。此时若有其他进程请求该资源,则请求进程只能等待。
不剥夺条件:进程所获得的资源在未使用完毕之前,不能被其他进程强行夺走,即只能 由获得该资源的进程自己来释放(只能是主动释放)。
请求和保持条件:进程已经保持了至少一个资源,但又提出了新的资源请求,而该资源 已被其他进程占有,此时请求进程被阻塞,但对自己已获得的资源保持不放。
循环等待条件:存在一种进程资源的循环等待链,链中每一个进程已获得的资源同时被 链中下一个进程所请求。即存在一个处于等待状态的进程集合{Pl, P2, ..., pn},其中Pi等 待的资源被P(i+1)占有(i=0, 1, ..., n-1),Pn等待的资源被P0占有,如图2-15所示。

jstack用于生成java虚拟机当前时刻的线程快照。线程快照是当前java虚拟机内每一条线程正在执行的方法堆栈的集合,生成线程快照的主要目的是定位线程出现长时间停顿的原因,如线程间死锁、死循环、请求外部资源导致的长时间等待等
一:jstack

jstack命令的语法格式: jstack  <pid>。可以用jps查看java进程id。这里要注意的是:

在实际运行中,往往一次 dump的信息,还不足以确认问题。建议产生三次 dump信息,如果每次 dump都指向同一个问题,我们才确定问题的典型性


tomcat设有最大线程数maxThreads和最大排队数acceptCount,这两个参数可以在server.xml文件中配置。tomcat处理请求可分为以下3种情况:
1.接收一个请求,当启动的线程数或正在运行的线程数< maxThreads时,则tomcat会启动一个线程来处理该请求;
2.接收一个请求,当启动的线程数或正在运行的线程数> maxThreads时,则tomcat会把请求放入等待队列,等待空闲线程执行请求;
3.接收一个请求,当启动的线程数或正在运行的线程数> maxThreads && 请求队列已满时,则tomcat会直接拒绝请求,此时客户端现象是connection refused(连接被拒绝)
如果大量的线程在执行请求的过程中由于IO阻塞,则导致线程池占满,服务则无法响应新的请求


死锁
死锁是由于多线程争夺互斥资源导致的。例如 1、2线程分别占用A、B锁,但同时在临界区代码中又需要B、A锁,由于各自获取了对方所需要的锁,最终导致死锁。
满足死锁的条件有以下四个,缺一不可:
1.互斥条件,即不能同时被两个或两个以上的线程占有;
2.不可抢占条件,即已占用的锁不能被其它线程抢夺;
3.占有且申请条件,即进程已经占有了一个锁,但又需要申请/等待另外一个锁;
4.循环等待条件,即等待其它线程的锁,而其它线程又等待更多线程的锁,且形成一个等待循环。
现象说明

jstack线程堆栈
线程堆栈如下所示,老套路从下往上看栈信息,线程Thread-6先锁0x00000000ebe97e18对象然后等待0x00000000ebe97e08;线程Thread-5先锁0x00000000ebe97e08对象然后待0x00000000ebe97e18,两个线程彼此等待,导致死锁BLOCKED (on object monitor)。

"Thread-6" #24 daemon prio=5 os_prio=0 tid=0x00007f6ce8ca6800 nid=0xbd7 waiting for monitor entry [0x00007f6d081f8000]
   java.lang.Thread.State: BLOCKED (on object monitor)
        at com.ljyhust.demo.service.DeadLockThreadDemo.getLockBA(DeadLockThreadDemo.java:42)
        - waiting to lock <0x00000000ebe97e08> (a java.lang.Object)
        - locked <0x00000000ebe97e18> (a java.lang.Object)
        at com.ljyhust.demo.web.ThreadTestDemoController$2.run(ThreadTestDemoController.java:89)
        at java.lang.Thread.run(Thread.java:748)

"Thread-5" #23 daemon prio=5 os_prio=0 tid=0x00007f6ce8576800 nid=0xbd6 waiting for monitor entry [0x00007f6d1cee3000]
   java.lang.Thread.State: BLOCKED (on object monitor)
        at com.ljyhust.demo.service.DeadLockThreadDemo.getLockAB(DeadLockThreadDemo.java:26)
        - waiting to lock <0x00000000ebe97e18> (a java.lang.Object)
        - locked <0x00000000ebe97e08> (a java.lang.Object)
        at com.ljyhust.demo.web.ThreadTestDemoController$1.run(ThreadTestDemoController.java:78)
        at java.lang.Thread.run(Thread.java:748)


package cn.tk.api.utils.security;
import org.apache.commons.codec.digest.DigestUtils;

public class md5 {
 public static void main(String args[]){
  String a="12345";
  String md5_a=DigestUtils.md5Hex(a);
  System.out.println(md5_a);
  
  String md5_a_upper=md5_a.toUpperCase();
  System.out.println(md5_a_upper);
  
  String md5_a_lower=md5_a.toLowerCase();
  System.out.println(md5_a_lower);
 }

}

原文地址:https://www.cnblogs.com/jingdenghuakai/p/13844561.html