同步方法实现卖票:
public class SaleTicket implements Runnable{
//库存票数
private int tickets=100;
/*
* 卖票 同步代码方法 比 同步代码块 性能高! 但是功能是一致的!
* 一个类中可以有多个 同步方法 或者同步代码块
*
* 当 一个对象调用这个对象中的同步方法时! 还可以同时调用其他的同步方法! 无需等待!
* 但是 一个对象执行这个对象中的同步代码块! 这个对象中的所有同步代码块 都上锁了! 都必须等待!
*
* 同步代码块 锁的是 对象 并不是 代码块!
*
*/
private synchronized void sale(){
if (tickets>0) {
System.out.println(Thread.currentThread().getName()+"卖出了"+tickets+"票");
//票数-1
tickets--;
}
try {
Thread.sleep(2); //让cpu重新分配时间片
} catch (InterruptedException e) {
e.printStackTrace();
}
}
@Override
public void run() {
while (tickets>0) {
sale();
}
}
public static void main(String[] args) {
SaleTicket ticket=new SaleTicket();
Thread t1=new Thread(ticket);
Thread t2=new Thread(ticket);
Thread t3=new Thread(ticket);
Thread t4=new Thread(ticket);
//设置窗口名称
t1.setName("1号窗口");
t2.setName("2号窗口");
t3.setName("3号窗口");
t4.setName("4号窗口");
//开始卖票
t1.start();
t2.start();
t3.start();
t4.start();
}
}
————————————————————————————
public class SaleTicket2 implements Runnable{ //库存票数 private int tickets=100; @Override public void run() { while (tickets>0) { //同步代码块 synchronized (this) { if (tickets>0) { System.out.println(Thread.currentThread().getName()+"卖出了"+tickets+"票"); //票数-1 tickets--; } try { Thread.sleep(2); //让cpu重新分配时间片 } catch (InterruptedException e) { //线程 阻塞异常! e.printStackTrace(); } } } } public static void main(String[] args) { SaleTicket2 ticket=new SaleTicket2(); Thread t1=new Thread(ticket); Thread t2=new Thread(ticket); Thread t3=new Thread(ticket); Thread t4=new Thread(ticket); //设置窗口名称 t1.setName("1号窗口"); t2.setName("2号窗口"); t3.setName("3号窗口"); t4.setName("4号窗口"); //开始卖票 t1.start(); t2.start(); t3.start(); t4.start(); } }
***********************************************
小结:
/* Runnable Thread Callable Future 多线程 Runnable 与 Callable 区别 01.Runnable默认规定执行的方法时run();Callable默认规定执行的方法时call(); 02.Runnable的run()没有返回值,Callable中的call()具有返回值 03.run()不能声明异常!必须内部处理! call()可以声明异常 04.运行Callable的时候可以 拿到一个Future对象 ! Future是一个模式! 核心思想====》 原本需要等待的时间段,现在可以去做一些其他的业务逻辑! 假设 现在有一个 具有返回值的A() 还有一个B() 和C() 之前我们调用A() 必须等待A()返回结构之后 才能调用 B()或者C() 现在我们调用A() 不须等待A()返回结构之后 也能调用 B()或者C() Future */
**********************************************************
多线程同步:
class MyThread implements Runnable{ /** * 同步代码方法 * 01.在不同的对象访问的时候,都可以进入这个方法 * 如果说锁住的是代码块,那么其他的对象就不会访问这个方法 * 02.在相同对象访问的时候,会开始 结束 输出完毕之后 继续下次的访问 */ public synchronized void test() { System.out.println("test()开始......"); try { Thread.sleep(1000); } catch (InterruptedException e) { e.printStackTrace(); } System.out.println("test()结束......"); } //线程要执行的run() public void run() { test(); //调用上面的代码 } public static void main(String[] args) { for (int i = 0; i < 3; i++) { /** * 每次都会创建一个新的对象 * 那么每个对象都会进入test() */ Thread thread = new Thread(new MyThread()); thread.start(); } } /** 相同的对象 * public static void main(String[] args) { MyThread myThread=new MyThread(); for (int i = 0; i < 3; i++) { // 只有一个新的对象那么对象会按照顺序进入test() Thread thread = new Thread(myThread); thread.start(); } } */ }
——————————————————————————
class MyThread01 implements Runnable{ /** * 同步代码块 效果和同步代码方法一样 * 01.在不同的对象访问的时候,都可以进入这个方法 * 如果说锁住的是代码块,那么其他的对象就不会访问这个方法 * 02.在相同对象访问的时候,会开始 结束 输出完毕之后 继续下次的访问 */ public void test() { //这是使用的是this 其实锁的还是当前的对象 synchronized(this){ System.out.println("test()开始......"); try { Thread.sleep(1000); } catch (InterruptedException e) { e.printStackTrace(); } System.out.println("test()结束......"); } } //线程要执行的run() public void run() { test(); //调用上面的代码 } public static void main(String[] args) { for (int i = 0; i < 3; i++) { /** * 每次都会创建一个新的对象 * 那么每个对象都会进入test() */ Thread thread = new Thread(new MyThread01()); thread.start(); } } /**相同的对象 * public static void main(String[] args) { MyThread myThread=new MyThread(); for (int i = 0; i < 3; i++) { // 只有一个新的对象那么对象会按照顺序进入test() Thread thread = new Thread(myThread); thread.start(); } } */ }
********************************************
锁住class对象
class MyThread02 implements Runnable{
public void test() {
/**
* 这是使用的是MyThread02.class 这是锁住类对应的class对象
* 其他的对象也是不能访问的!
*/
synchronized(MyThread02.class){
System.out.println("test()开始......");
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("test()结束......");
}
}
//线程要执行的run()
public void run() {
test(); //调用上面的代码
}
public static void main(String[] args) {
for (int i = 0; i < 3; i++) {
Thread thread = new Thread(new MyThread02());
thread.start();
}
}
/**相同的对象
* public static void main(String[] args) {
MyThread myThread=new MyThread();
for (int i = 0; i < 3; i++) {
// 只有一个新的对象那么对象会按照顺序进入test()
Thread thread = new Thread(myThread);
thread.start();
}
}
*/
}