1.多线程的创建
java中要实现多线程有好多种方式,其中最基本的两种为继承Thread类重写run方法或者实现runnable接口
2.线程的状态
新生 阻塞 就绪 运行 死亡
3.多线程创建的方法
继承了Thread类.start();
new Thread(new 实现了runnable接口的类 ,线程名字(此参数可有可无)).start(); (代理模式)
4.sleep 线程进入阻塞状态,但持有所的话是不会放开锁的
join
线程A{
代码块
线程B.join();
}
线程B插队运行,线程A阻塞直到B运行完
yield 从运行进入就绪,有可能刚下CPU又被调度上CPU
wait 放开锁进入阻塞
notify notifyAll 通知其他wait阻塞的线程可以运行了
通过wait 和notify 可以实现通过信号量手动加锁
5synchronized关键字的用法
synchronized锁方法
public synchronized void test(){ }
如果多个线程调用一个对象中的此方法
public class Test implements Runnable{
public synchronized void test(){
System.out.println(Thread.currentThread().getName());
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println(Thread.currentThread().getName());
}
@Override
public void run() {
test();
}
public static void main(String[] args) {
Test t1 = new Test();
new Thread(t1,"1").start();
new Thread(t1,"2").start();
new Thread(t1,"3").start();
}
}
结果为
1
1
2
2
3
3
若将main方法改为
public static void main(String[] args) {
Test t1 = new Test();
Test t2 = new Test();
Test t3 = new Test();
new Thread(t1,"1").start();
new Thread(t2,"2").start();
new Thread(t3,"3").start();
}
则结果为
1
3
2
2
1
3
证明其锁的是不同线程对同一对象(地址)的加锁方法同时只能有一个线程访问
锁对象
与锁方法相同在,被锁的语句块里被锁的地址只能有一个线程访问
public class Test implements Runnable{
Object A = new Object();
public void test(){
synchronized (this) {
System.out.println(Thread.currentThread().getName());
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println(Thread.currentThread().getName());
}
}
@Override
public void run() {
test();
}
public static void main(String[] args) {
Test t1 = new Test();
new Thread(t1,"1").start();
new Thread(t1,"2").start();
new Thread(t1,"3").start();
}
}
显而易见的结果为
1
1
3
3
2
2
而如果将test方法改为
public void test(){ synchronized (A) {
System.out.println(Thread.currentThread().getName());
try {
Thread.sleep(1000);
} catch (InterruptedException e) { // TODO Auto-generated catch block e.printStackTrace(); } System.out.println(Thread.currentThread().getName()); } }
结果也是相同的
而锁this和锁非this的区别参见