标题: java多线程之同步 [打印本页] 作者: 新手ing 时间: 2015-7-16 22:04 标题: java多线程之同步 1、看一个卖票例子
需求:100张票,写一个多线程卖票的程序。
public class Demo1 {
public static void main(String[] args) {
ticket t = new ticket();
Thread t1 = new Thread(t);
Thread t2 = new Thread(t);
Thread t3 = new Thread(t);
Thread t4 = new Thread(t);
t1.start();
t2.start();
t3.start();
t4.start();
}
}
class ticket implements Runnable{
private int tickets = 100;
boolean more = true;
public void run() {
while (more) {
if (tickets > 0) {
System.out.println(Thread.currentThread().getName()
+ "...sale:" + tickets--);
}else {
more = false;
}
}
}
}
以上程序会出现一个问题:比如还剩下1张票,0线程进来,刚判断完,时间片轮转结束,1线程进来,刚判断完,时间片轮转结束,2线程进来,时间片轮转结束,3线程进来时间片轮转结束,现在4个进程都处于可执行状态,等待处理器调度。0线程获得CPU执行权,打印ticket=1;接着1线程打印ticket=0.接着2线程打印ticket=-1;接着3线程打印ticket=-2;出现问题了。
当多线程操作共享数据,一个线程还未执行完,另一个线程进来,破坏了线程的完整性。
引入锁机制 同步代码块 Object锁。
public class Demo2 {
public static void main(String[] args) {
ticket t = new ticket();
Thread t1 = new Thread(t);
Thread t2 = new Thread(t);
Thread t3 = new Thread(t);
Thread t4 = new Thread(t);
t1.start();
t2.start();
t3.start();
t4.start();
}
}
class ticket implements Runnable {
private int tickets = 100;
boolean more = true;
Object obj = new Object();
public void run() {
synchronized (obj) {
while (more) {
if (tickets > 0) {
try {
Thread.sleep(10);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
System.out.println(Thread.currentThread().getName()
+ "...sale:" + tickets--);
} else {
more = false;
}
}
}
}
}
同步函数解决同步问题
public class Demo2 {
public static void main(String[] args) {
ticket t = new ticket();
Thread t1 = new Thread(t);
Thread t2 = new Thread(t);
Thread t3 = new Thread(t);
Thread t4 = new Thread(t);
t1.start();
t2.start();
t3.start();
t4.start();
}
}
class ticket implements Runnable {
private int tickets = 100;
boolean more = true;
public synchronized void run() {
while (more) {
if (tickets > 0) {
try {
Thread.sleep(10);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
System.out.println(Thread.currentThread().getName()
+ "...sale:" + tickets--);
} else {
more = false;
}
}
}
}