Java用同步代码块实现线程同步:
本文示例卖票的,三张票,四个窗口出售
testsale1为四个线程处理同一个对象,sale1内有两个方法,可供run方法调用,一个是未使用同步代码块的方法,一个是使用同步代码块的方法
testsale2为四个线程处理四个对象,对象不同,但可以同步,直接将同步代码块写入run方法Thread.start()和Thread.run()的区别:
start是进入就绪不一定去执行,该线程执行时会自动调用内部的run方法。
调用run的话会直接执行。自动将当前线程变为主线程,并没有实现分线程。
这一点区别可以使用Thread.currentThread().getName()进行验证
废话不多说,关于卖票多线程实现方法和具体解释看代码
如果看不出来,连续多运行几次就能看出区别
注释表示可选的验证
package ticket;
public class ticket {
public static void main(String[] args) {
testsale1();
testsale2();
}
/**
* 测试sale1的方法 多个线程处理同一对象 实现线程同步
*/
public static void testsale1() {
sale1 s = new sale1();
Thread t1 = new Thread(s, "windows 1");
Thread t2 = new Thread(s, "windows 2");
Thread t3 = new Thread(s, "windows 3");
Thread t4 = new Thread(s, "windows 4");
t1.start();
t2.start();
t3.start();
t4.start();
}
/**
* 测试sale2的方法 多个线程处理不同对象 实现线程同步
*/
public static void testsale2() {
sale2 s1 = new sale2();
sale2 s2 = new sale2();
sale2 s3 = new sale2();
sale2 s4 = new sale2();
Thread t1 = new Thread(s1, "windows 1");
Thread t2 = new Thread(s2, "windows 2");
Thread t3 = new Thread(s3, "windows 3");
Thread t4 = new Thread(s4, "windows 4");
t1.start();
t2.start();
t3.start();
t4.start();
}
}
/**
* 一个类可以包含多个类,至少一个是public 下面类实现的是 使用同步代码块的多线程和没有使用同步代码块的多线程区别
* 使用的可以确保进入该代码块的只有一个线程 没有使用的不能保证进入该代码快的是一个线程
*
* @author Administrator
*
*/
class sale1 implements Runnable {
static int remainticket = 3;
@Override
public void run() {
// TODO Auto-generated method stub
// saleTicket();
sysale();
}
/**
* 没使用同步代码快标记的方法 该方法,可导致线程不稳定,输出结果不一致
*/
private void saleTicket() {
// TODO Auto-generated method stub
if (remainticket > 0) {
remainticket--;
System.out.println(Thread.currentThread().getName() + " " + remainticket);
// remainticket--;
} else {
System.out.println(Thread.currentThread().getName() + " " + "no ticket");
}
}
/**
* 使用同步代码块控制的方法 可以保证线程执行时只有一个线程调用该方法
*/
public synchronized void sysale() {
if (remainticket > 0) {
remainticket--;
System.out.println(Thread.currentThread().getName() + " " + remainticket);
// remainticket--;
} else {
System.out.println(Thread.currentThread().getName() + " " + "no ticket");
}
}
}
/**
* 一个类可以包含多个类,至少一个是public 下面类实现的是 重写run方法在方法内实现同步代码块
*
* @author Administrator
*
*/
class sale2 implements Runnable {
static int remainticket = 3;
/**
* 将同步代码块直接写入run方法 synchronized (实现同步代码块的类名.class)
*/
@Override
public void run() {
// TODO Auto-generated method stub
synchronized (sale2.class) {
if (remainticket > 0) {
remainticket--;
System.out.println(Thread.currentThread().getName() + " " + remainticket);
// remainticket--;
} else {
System.out.println(Thread.currentThread().getName() + " " + "no ticket");
}
}
}
}