线程不是什么时髦的技术,它是最基本的技术
线程:就是程序执行的一条线索,如图
一 创建线程的两种方式
1 在Thread 子类覆盖的 run 方法中编写代码
2 在传递给Thread 对象的Runnable 对象的run方法中编写代码
以下一个示例
/**
* 一个传统的线程类
*/
public class TraditionalThread {
public static void main(String[] args) {
/** 第一种实现方式, 重写 run 方法*/
Thread thread = new Thread(){
@Override
public void run(){
while(true)
{
try {
Thread.sleep(500);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("1 " + Thread.currentThread().getName());
}
}
};
thread.start();
/**第二种方式,实现Runnable 接口*/
Thread thread2 = new Thread(new Runnable(){
@Override
public void run() {
while(true)
{
try {
Thread.sleep(500);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("2 "+Thread.currentThread().getName());
}
}
});
thread2.start();
/**第三种方式,(){}这种写法表示定义了一个子类,此时()里面是空的,等于11行
* Thread(new Runnable()) 这表示在构造方法中定义了一个类
* 因此代码执行顺序,先走打印 thread这行,再到构造方法中运行 打印runnable
* 由于Runnable 是父接口,子类已有run方法,代码只会走子类,永远不会走 打印runnable*/
new Thread(new Runnable(){
@Override
public void run() {
while(true)
{
try {
Thread.sleep(500);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("runnable "+Thread.currentThread().getName());
}
}
})
{
public void run(){
while(true)
{
try {
Thread.sleep(500);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("thread "+Thread.currentThread().getName());
}
}
}.start();
}
}
运行结果
多线程并不会提高效率
注意一个概念: 多线程下载, 用户端并没有快,而是占用了服务器的带宽
二 线程的互斥与同步通信
线程安全问题可以用银行转帐来解释,如图
如果一段代码要实现原子性,就是说如果有一个线程在执行该代码时,别的线程不能执行,就像WC里的坑,只要有一个人占用,别的人就绝对不能进来
要实现这个功能,就要将必须完整执行的代码 放在 synchorized (object){} , 但是要注意在一段代码里,如果用2个synchorized ,极可能出现死锁
通常有两个方式:
1. 使用 synchronized 代码及其原理
2. 使用 synchronized 方法
效果如下:
以上两部分具体代码 请参见 ThreadCourse工程