文章目录
1.代码分析
public class Person {
private Integer pId;
private String pName;
private Random random = new Random();
// 计算器
private static Object calculator = new Object();
public Person() {
}
public Person(Integer pId, String pName) {
this.pId = pId;
this.pName = pName;
}
// 做某些事情
public void doSomething() {
int thingType = random.nextInt(3);
int sum = 0;
switch (thingType) {
case 0: // 轻
sum = this.sum0();
break;
case 1: // 中
sum = this.sum1();
break;
case 2: // 重
sum = this.sum2();
break;
default:
break;
}
// System.out.println("thingType=" + thingType + " sum=" + sum);
}
// 轻活
private int sum0() {
int a = 1, b = 1;
int sum = a + b;
return sum;
}
// 中活
private int sum1() {
int sum = 0;
for (int i = 0; i < 1000; i++) {
sum += i;
sum += i - sum;
}
return sum;
}
// 重活
private int sum2() {
int sum = 0;
for (int i = 0; i < 100000; i++) {
sum += (i % 10);
sum += (sum % 10);
sum += (sum % 10);
}
return sum;
}
public static void main(String[] args) {
for (int i = 0; i < 6; i++) {
final int num = i;
new Thread() {
@Override
public void run() {
Thread.currentThread().setName("子线程_"+num);
while (true){
int pid = 0;
// 不停的创建对象,并打印他的名字
Person person = new Person(pid,"person_" + pid );
// 做某些事情
person.doSomething();
try {
Thread.sleep(50);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
};
}.start();
}
}
2.线程
2.1 线程历史记录
2.1.1 线程运行和等待
2.1.2 线程阻塞
修改一下代码:
public void doSomething() {
try{
lock.lock();
this.sum2();
}finally {
lock.unlock();
}
}
public static void main(String[] args) {
final Person person = new Person();
for (int i = 0; i < 6; i++) {
final int num = i;
new Thread() {
@Override
public void run() {
Thread.currentThread().setName("子线程_"+num);
while (true){
int pid = 0;
// 不停的创建对象,并打印他的名字
person.setpId(pid);
person.setpName("person_" + pid);
// 做某些事情
person.doSomething();
try {
Thread.sleep(10);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
};
}.start();
}
}
则可以看到阻塞状态
上述若红色占用太多的话,就要考虑代码效率是否要优化一下了
2.1.3 线程IO阻塞
修改代码:
public void doSomething() {
httpIO();
}
private String httpIO() {
String url = "http://www.taobao.com";
String result = "";
BufferedReader in = null;
try {
URL realUrl = new URL(url);
HttpURLConnection conn = (HttpURLConnection) realUrl.openConnection();
// 通用设置
conn.setRequestProperty("accept", "*/*");
conn.setRequestProperty("connection", "Keep-Alive");
conn.setRequestProperty("user-agent", "Mozilla/4.0 (comptibal; MSIE 6.0; Windows NT 5.1;SV1 )");
// 不使用缓存
conn.setUseCaches(false);
// 建立链接
conn.connect();
in = new BufferedReader(new InputStreamReader(conn.getInputStream()));
String line;
while (null != (line = in.readLine())) {
result += line;
}
} catch (IOException e) {
e.printStackTrace();
} finally {
if (null != in) {
try {
in.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
return result;
}
2.1.4 线程死亡
public static void main(String[] args) {
final Person person = new Person();
for (int i = 0; i < 6; i++) {
final int num = i;
//6个线程中,随机产生数字,用这个数字表示每个线程执行多少次完成后死亡
final int survivalMaxCount = 10 + new Random().nextInt(10);
new Thread() {
@Override
public void run() {
Thread.currentThread().setName("子线程_"+num);
int pid = 0;
while (true){
// 不停的创建对象,并打印他的名字
person.setpId(pid);
person.setpName("person_" + pid++);
// 做某些事情
person.doSomething();
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
if(pid > survivalMaxCount){
break;
}
}
};
}.start();
}
//保活线程,主要是表示该线程每秒都在执行,不会死亡
new Thread(new Runnable() {
@Override
public void run() {
try {
while (true){
Thread.currentThread().setName("活动线程");
TimeUnit.SECONDS.sleep(1);
}
} catch (InterruptedException e) {
}
}
}).start();
}
2.2 Thread Moniter 线程监视器
比较简单,就是查看线程状态的
2.3 Thread Dumps 线程快照
线程快照,可跟踪某一时刻的线程状态
public class Person {
private Integer pId;
private String pName;
// 计算器
private static Object calculator = new Object();
private Lock lock = new ReentrantLock();
public Person() {
}
public Person(Integer pId, String pName) {
this.pId = pId;
this.pName = pName;
}
// 做某些事情
public void doSomething() {
// try{
// lock.lock();
// this.sum2();
// }finally {
// lock.unlock();
// }
synchronized (calculator){
this.sum2();
}
}
public static void main(String[] args) {
final Person person = new Person();
for (int i = 0; i < 6; i++) {
final int num = i;
new Thread() {
@Override
public void run() {
Thread.currentThread().setName("子线程_"+num);
int pid = 0;
while (true){
// 不停的创建对象,并打印他的名字
person.setpId(pid);
person.setpName("person_" + pid++);
// 做某些事情
person.doSomething();
try {
Thread.sleep(1);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
};
}.start();
}
}
3. Monitors & locks
Attach mode下不可以用这个功能。那我们就用IDEA打开程序
正常竞争锁代码
// 做某些事情
public void doSomething() {
// try{
// lock.lock();
// this.sum2();
// }finally {
// lock.unlock();
// }
synchronized (calculator){
this.sum2();
}
}
public static void main(String[] args) {
final Person person = new Person();
for (int i = 0; i < 6; i++) {
final int num = i;
new Thread() {
@Override
public void run() {
Thread.currentThread().setName("子线程_"+num);
int pid = 0;
while (true){
// 不停的创建对象,并打印他的名字
person.setpId(pid);
person.setpName("person_" + pid++);
// 做某些事情
person.doSomething();
try {
Thread.sleep(1);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
};
}.start();
}
}
3.1 Current Locking Graph
3.2 Current Monitors
3.3 Locking History Graph
3.4 Monitor History
4.死锁演示
死锁代码: