一.
怎么解决程序的安全性问题。
就相当于不给其他线程机会,自己独占。
对于多条语句的封装通常用什么封装?花括号,也就是代码块。
我们现在需要这个代码块具备一定的功能,多个线程只能每次有一个线程进来操作。这个我们也可以用一个关键字来标识。
synchronized是同步的意思,
写同步代码块的时候,必须要明确是对那些代码进行同步,如果不清楚的话,就不要写同步代码块。
这里面有个对象,这个对象代表什么呢?对象相当于一个标记,标志。
那synchronized里面放什么对象,我们这里也没有对象。干脆造一个对象,
将造好的对象放置到synchronized中,为了同步造个对象有点多余。那怎么办?
我们找一个现成的对象就好了,干嘛造自然描述对象。
现在就解决了安全问题,编译运行当前程序。
但是整个结果来看,都是一个线程在运作。安全隐患是解决了,没有负数的票号出现了。但是咱程序中写的是四个线程。
再次编译运行,出现了多个
从结果来看,运行了四个线程,1和2线程有资格,没抢到执行权。
接下来的问题就是synchronized是怎么保证没有安全问题的呢?
package test; /* * 需求,卖票 * * 线程安全问题产生的原因 * 前提: *1.多个线程在操作共享的数据。多线程哦 *2.操作共享数据的线程代码有多条。共享数据,多个线程操作。 * *当一个线程在执行操作共享数据的多条代码中,其他线程参与了运算 *就会导致线程安全问题的产生 * *解决思路: * *就是将多条操作共享数据的线程代码封装起来,当有线程在执行这些代码的时候,其他线程是不可以参与运算的的 * *必须要当前线程把这些代码都执行完毕后,其他线程才可以参与运算。 * *在java中,用同步代码块解决这个问题 * *同步代码块的格式: *synchronized(对象) *{ *需要被同步的代码块 *} * *同步的好处:解决了线程的安全问题 *同步的弊端:相对降低了效率,因为同步外的线程的都会判断同步锁 * *同步的前提: *同步中必须有多个线程并使用同一个锁。 */ class Ticket implements Runnable { private static int num = 10; Object obj = new Object(); public void run() { while(true) { synchronized (obj) { if(num>0) { try { Thread.sleep(10); } catch (InterruptedException e) { // TODO: handle exception } System.out.println(Thread.currentThread().getName()+"..sale..."+num--); } } } } } public class RunnableDemo { 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(); } }