茂展的分享博客

多线程总结(四)

线程总结(四)

怎么检测一个线程是否拥有锁?

  1. 可以调用wait()方法,如果出现异常,就说明java中的线程没有持有锁。否则将持有锁。(这种方式不推荐)
  2. 我们可以使用API,Thread的一个静态方法boolean isHave = Thread.holdsLock(User.class);如果存在则返回true,没有持有User这个对象的锁,则返回false;

Jdk中排查多线程问题用什么命令

jstack

作用: 生成JVM当前时刻线程的快照(threaddump,当前进程中所有线程的信息)
目的:帮助快速定位程序问题出现的原因,如长时间停顿、cpu占用率过高。

向线程传递参数的三种基本方法

1. 通过构造方法传递数据

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
package com.nyist.thread;

public class MyThread extends Thread
{
private String name;

public MyThread(String name)
{
this.name = name;
}
public void run()
{
System.out.println("hello " + name);
}
public static void main(String[] args)
{
Thread thread = new MyThread("demo");
thread.start();
}
}

2.通过变量和方法传递数据

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
package com.nyist.thread;

public class MyThread1 implements Runnable
{
private String name;

public void setName(String name)
{
this.name = name;
}
public void run()
{
System.out.println("hello " + name);
}
public static void main(String[] args)
{
MyThread2 myThread = new MyThread2();
myThread.setName("demo");
Thread thread = new Thread(myThread);
thread.start();
}
}

3.通过回调函数传递数据

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.nyist.thread;

class Data
{
public int value = 0;
}
class Work
{
public void process(Data data, Integer numbers)
{
for (int n : numbers)
{
data.value += n;
}
}
}
public class MyThread2 extends Thread
{
private Work work;

public MyThread3(Work work)
{
this.work = work;
}
public void run()
{
java.util.Random random = new java.util.Random();
Data data = new Data();
int n1 = random.nextInt(1000);
int n2 = random.nextInt(2000);
int n3 = random.nextInt(3000);
work.process(data, n1, n2, n3); // 使用回调函数
System.out.println(String.valueOf(n1) + "+" + String.valueOf(n2) + "+"
+ String.valueOf(n3) + "=" + data.value);
}
public static void main(String[] args)
{
Thread thread = new MyThread3(new Work());
thread.start();
}
}

锁的降级和升级

ReadWriteLock是读写锁接口,里面有两个方法

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
public interface ReadWriteLock {
/**
* Returns the lock used for reading.
*
* @return the lock used for reading
*/
Lock readLock();

/**
* Returns the lock used for writing.
*
* @return the lock used for writing
*/
Lock writeLock();
}

一个是读锁,一个写锁

降级锁: 由写锁到读锁

升级锁: 由读锁到写锁

1
2
3
4
5
6
7
8
9
10
11
12
13
14
package com.nyist.thread;

import java.util.concurrent.locks.ReentrantReadWriteLock;

public class Test1 {

public static void main(String[] args) {
ReentrantReadWriteLock rtLock = new ReentrantReadWriteLock();
rtLock.readLock().lock();
System.out.println("获得读锁.");
rtLock.writeLock().lock();
System.out.println("阻塞");
}
}

结果打印出来是 获得读锁. 这说明ReentrantReadWriteLock不可以锁升级

1
2
3
4
5
6
7
8
9
10
11
12
13
14
package com.nyist.thread;
import java.util.concurrent.locks.ReentrantReadWriteLock;

public class Test2 {

public static void main(String[] args) {
ReentrantReadWriteLock rtLock = new ReentrantReadWriteLock();
rtLock.writeLock().lock();
System.out.println("写锁");

rtLock.readLock().lock();
System.out.println("获得读锁");
}
}

结果打印出来是 写锁 获得读锁 这说明ReentrantReadWriteLock可以锁降级

FutureTask和Future区别

Future是一个接口,代表可以取消的任务,并且返回执行的结果。
FutureTask是实现了Futrue和Runnable接口

------本文结束感谢阅读------
🐶 您的支持将鼓励我继续创作 🐶