标签:容器 info creat block 内核 http ++ src 多线程
多线程的内容有的是笔者自己总结,有的会直接推荐优质博客。
自己总结的部分一般包含个人实践时的经验和需要注意的坑点。
三种方式的核心均是对Thread类中run方法进行override
public class CreateThreadMethod {
public static void main(String[] args) {
extendsMethod thread = new extendsMethod();
thread.start();
}
}
class extendsMethod extends Thread {
@Override
public void run() {
for (int i = 9; i >= 0; i--) {
System.out.println("extendsMethod's Thread:" + i);
try {
Thread.sleep(500);
} catch (InterruptedException e) {
}
}
}
}
public class CreateThreadMethod {
public static void main(String[] args) {
Thread thread = new Thread(new implementsMethod());
thread.start();
}
}
class implementsMethod implements Runnable {
@Override
public void run() {
for (int i = 0; i < 10; i++) {
System.out.println("implementsMethod's Thread:" + i);
try {
Thread.sleep(500);
} catch (InterruptedException e) {
}
}
}
}
多线程创建方式:
public class CreateThreadMethod {
public static void main(String[] args) {
Thread thread = new Thread(new Runnable() {
@Override
public void run() {
for (int i = 9; i >= 0; i--) {
System.out.println("The third method's Thread:" + 3 * i);
try {
Thread.sleep(500);
} catch (InterruptedException e) {
}
}
}
});
thread.start();
}
}
有关匿名类在构造函数中使用的说明:
先看如下例子:
public class ThisEscape {
private final int num;
public ThisEscape(EventSource source) {
//在构造函数中直接使用匿名类
source.registerListener(
new EventListener() {
public void onEvent(Event e) {
doSomething(e);
}
});
num = 42;
}
private void doSomething(Event e) {
if (num != 42) {
System.out.println("Race condition detected at " +
new Date());
}
}
}
上述class编译之后分为两部分:
outer class:
public class ThisEscape {
private final int num;
public ThisEscape(EventSource source) {
source.registerListener(new ThisEscape$1(this));
num = 42;
}
private void doSomething(Event e) {
if (num != 42)
System.out.println(
"Race condition detected at " + new Date());
}
static void access$000(ThisEscape _this, Event event) {
_this.doSomething(event);
}
}
anonymous inner class:
class ThisEscape$1 implements EventListener {
final ThisEscape this$0;
ThisEscape$1(ThisEscape thisescape) {
this$0 = thisescape;
super();
}
public void onEvent(Event e) {
ThisEscape.access$000(this$0, e);
}
}
试想:如果一个线程足够快,那么就有可能在num
还被初始化为42之前,匿名类已经调用了doSomething()
这个时候就会抛出NullPointerException
那么一个类的构造函数要怎么写才会避免类似的错误出现呢?
static
、non-static
this
当成参数传递给其他的类或方法private
方法详见博客:多线程的核心理论
对方法加锁 == 对对象加锁,即synchronized this
关于synchronized
的内核剖析详见博客:synchronized的内核剖析
个人使用经验是:对于一些标志位,常采用volatile
关于volatile的具体解析:volatile
思考:图中涉及的wait方法和sleep方法,为什么wait方法在Object类,而sleep方法在Thread类?
两者都可以让线程暂停一段时间,但是本质的区别在于sleep方法是线程的运行状态控制,而wait方法是线程之间的通讯
详见博客:线程安全的容器
标签:容器 info creat block 内核 http ++ src 多线程
原文地址:https://www.cnblogs.com/joeye153/p/12539177.html