线程互斥的解决方案:用锁。
核心:保证竞争统一资源的所有线程用同一把锁
demo:讲解的不同场景下,锁的设计。
package 多线程;
import 多线程.TraditionalThreadSynchronized.Outputer;
public class TraditionalThreadSynchronized2 {
public static void main(String[] args) {
/*
* 原则:同一把锁
*
* 为了避免资源争抢
* 加一个锁 排他性
* synchronized在关键代码中
*
*
* */
new TraditionalThreadSynchronized2().init();
}
private void init() {
/*
* 静态方法不能new内部类的实例对象:
*
* 内部类可以访问外部类的成员变量 而外部类的成员变量和对象绑定
*
* 而静态方法执行的时候可以没有对象,矛盾
*/
// final Outputer outputer=new Outputer();
// 第一个线程
Outputer outputer = new Outputer();// 内部类不能访问局部变量
new Thread(new Runnable() {
@Override
public void run() {
while (true) {
try {
Thread.sleep(10);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
outputer.output("zhangsan");
/*New OutPut().output("zhangsan");
* 若是这种形式则,不能保证锁是同一把
* 会有线程安全的问题
*/
}
}
}).start();
// 另一个线程
new Thread(new Runnable() {
@Override
public void run() {
while (true) {
try {
Thread.sleep(10);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
outputer.output2("lisi");
}
}
}).start();
}
static class Outputer {
//第一种互斥是保护方法中的一小段代码:
//可以重新定义一个String lock="";
//也可以用对象的本身来定义锁this
public void output(String name) {
int len = name.length();
//加一个排他性锁
//若是synchronized (name) 不行,
//因为两个线程的锁不是同一把
//所以必须定义一个同一个变量
//synchronized (lock)
synchronized (Outputer.class){
for (int i = 0; i < len; i++) {
System.out.print(name.charAt(i));
}
System.out.println();
}
}
/*第二种互斥是保护整个方法:
* public synchronized void output2()
*/
public synchronized void output2(String name) {
int len = name.length();
for (int i = 0; i < len; i++) {
System.out.print(name.charAt(i));
}
System.out.println();
}
//静态方法:则锁用类的字节码。Outputer.class;
public static synchronized void output3(String name) {
int len = name.length();
for (int i = 0; i < len; i++) {
System.out.print(name.charAt(i));
}
System.out.println();
}
}
}