线程(二)
线程的几个方法
- join:相对于main线程来加入 ,会加在main线程前执行
- Priority:线程的优先级,最大10,最小1,中是5.
- yield:让位
- Daemon:守护线程,比如:GC,垃圾回收器
对象锁和类锁
synchronized 加到 static 方法前面是给class 加锁,即类锁;而synchronized 加到非静态方法前面是给对象上锁。
对象锁和类锁是不同的锁,所以多个线程同时执行这2个不同锁的方法时,是异步的。
类锁对该类的所有对象都能起作用,而对象锁不能。
大白话就是:一个线程执行同步的静态方法后,另一个线程就得等第一个线程执行完这个方法后才能继续执行。但是第二个线程可以异步地去执行非静态方法。
对象锁
设置sychronized的两种方式
package com.pro.test6;
public class Syn {
public void m1(){
//同步块
synchronized (this) {
for (int i = 0; i < 5; i++) {
System.out.println("m1-->" + i);
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
try {
Thread.sleep(10000);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
public synchronized void m2(){
for (int i = 0; i < 5; i++) {
System.out.println("m2-->"+i);
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
测试类调用
package com.pro.test6;
public class Test1 {
public static void main(String[] args) {
final Syn syn=new Syn();
final Syn syn1=new Syn();//不同对象没有互斥关系
//这里要强调,一个对象一把锁,这个锁会锁住所有标识为synchronized
//的方法或块。
//放置在方法和块有什么区别?同步块更优化。
//徐达
Thread t1=new Thread(new Runnable() {
public void run() {
//任务?
syn.m1();
}
},"t1");
//谷忠富
Thread t2=new Thread(new Runnable() {
public void run() {
//任务?
syn1.m2();
}
},"t2");
t1.start();
t2.start();
}
}
结果图
类锁
- 记住:静态方法,如果加上了synchronized,所有对象都要排队。
- 因为类型只有一个,大家来访问,必须要排队。
- 而非静态方法加上synchronized,因为是对象的方法,那对象上是有锁的。
- 这个锁不仅仅只锁了一个方法,而是锁了这个对象的所有synchronized方法。
- 所以说,这个对象没有退出synchronized方法,则其他方法也是被锁的。
- 问题:synchronized的静态方法和非静态方法,有什么不同?
public class Syn {
public void m1(){
synchronized (Syn.class) {
for (int i = 0; i < 5; i++) {
System.out.println("m1-->" + i);
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
public synchronized static void m2(){
for (int i = 0; i < 5; i++) {
System.out.println("m2-->"+i);
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
测试类
public class Test1 {
public static void main(String[] args) {
final Syn syn=new Syn();
final Syn syn1=new Syn();//不同对象没有互斥关系
//徐达
Thread t1=new Thread(new Runnable() {
public void run() {
//任务?
syn.m1();
}
},"t1");
//谷忠富
Thread t2=new Thread(new Runnable() {
public void run() {
//任务?
syn.m2();
}
},"t2");
t1.start();
t2.start();
}
}
结果图
最后可以通过object的两个方法实现线程的分时运行
this.notifyAll();唤醒所有线程
this.wait();等待
public class Data {
private int num;
public Data(int num) {
this.num = num;
}
public synchronized void printOdd(){
System.out.println("printOdd,"+Thread.currentThread().getName()+"-->"+(num++));
this.notifyAll();
try {
Thread.sleep(1000);
this.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
public synchronized void printEven(){
System.out.println("printEven,"+Thread.currentThread().getName()+"-->"+(num++));
this.notifyAll();
try {
Thread.sleep(1000);
this.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
结果图