安徽建设厅网站施,discuz!网站模板,老薛主机做电影网站,河南建设部网站文章目录 1. Runnable接口2. 卖票案例3. 同步代码块解决数据安全问题4. 同步方法解决数据安全问题5. 线程安全的类6. Lock锁 1. Runnable接口 1. 创建线程的另一种方法是声明一个实现Runnable接口的类#xff0c;之后重写run()方法#xff0c;然后可以分配类的实例#xff0… 文章目录 1. Runnable接口2. 卖票案例3. 同步代码块解决数据安全问题4. 同步方法解决数据安全问题5. 线程安全的类6. Lock锁 1. Runnable接口 1. 创建线程的另一种方法是声明一个实现Runnable接口的类之后重写run()方法然后可以分配类的实例在创建Thread时作为参数传递最后启动。 2. 具体实现Runnable接口(1) 定义一个MyRunnable实现Runnable接口。 (2) 在MyRunnable中重写run()方法。 (3) 创建MyRunnable类对象。 (4) 创建Thread类的对象把MyRunnable对象作为构造方法的参数。 (5) 启动线程。
public class MyRunnable implements Runnable{Overridepublic void run() {for(int i0;i100;i){System.out.println(Thread.currentThread().getName():i);}}
}public class MyRunnableDemo {public static void main(String[] args) {//创建MyRunnable类对象MyRunnable mynew MyRunnable();//创建Thread类对象,把MyRunnable对象作为参数传进来//Thread(Runnable target)//Thread t1new Thread(my);//Thread t2new Thread(my);//Thread(Runnable target, String name)Thread t1new Thread(my,线程1);Thread t2new Thread(my,线程2);//启动线程t1.start();t2.start();}
}3. 多线程的实现方案有两种(1) 继承Thread类。 (2) 实现Runnable接口。
实现Runnable接口好处避免了Java单继承的局限性适合多个相同程序的代码去处理同一资源的情况把线程和程序的代码、数据有效分离较好地体现了面向对象的设计思想。
2. 卖票案例 1. 需求和思路 2. 代码块
public class SellTicket implements Runnable{//表示有100张票private int tickets100;Overridepublic void run() {while (true){if(tickets0){System.out.println(Thread.currentThread().getName()正在出售第tickets张票);tickets--;}}}
}public class SellTicketDemo {public static void main(String[] args) {SellTicket stnew SellTicket();Thread t1new Thread(st,窗口1);Thread t2new Thread(st,窗口2);Thread t3new Thread(st,窗口3);t1.start();t2.start();t3.start();}
}3. 问题分析看上面结果相同的票会出现三次为什么呢请参照下图理解虽然加上了休眠时间但是原理是一样的都是线程抢占CPU执行权导致的。 3. 同步代码块解决数据安全问题 1. 如何解决多线程安全问题(1) 把多条语句操作共享数据的代码给锁起来让任意时刻只能有一个线程执行即可。 (2) Java提供了同步代码块的方式来解决。 2. 同步代码块格式 3. 代码块举例
public class SellTicket implements Runnable{//表示有100张票private int tickets100;private Object obj new Object();Overridepublic void run() {while (true){synchronized (obj) {if (tickets 0) {System.out.println(Thread.currentThread().getName() 正在出售第 tickets 张票);tickets--;}}}}
}public class SellTicketDemo {public static void main(String[] args) {SellTicket stnew SellTicket();Thread t1new Thread(st,窗口1);Thread t2new Thread(st,窗口2);Thread t3new Thread(st,窗口3);t1.start();t2.start();t3.start();}
}4. 同步的好处和弊端(1) 好处解决了多线程的数据安全问题。 (2) 弊端当线程很多时因为每个线程都会去判断同步上的锁这是很耗费资源的无形中会降低程序的运行效率。
4. 同步方法解决数据安全问题 1. 同步方法就是把synchronized关键字加到方法上。 2. 格式修饰符 synchronized 返回值类型 方法名(方法参数){ }。 3. 同步方法的锁对象this。 4. 代码块举例
public class SellTicket implements Runnable{//表示有100张票private int tickets100;private Object obj new Object();private int x0;Overridepublic void run() {while (true){if(x%20) { //这里得是this否则会出问题synchronized (this) {if (tickets 0) {System.out.println(Thread.currentThread().getName() 正在出售第 tickets 张票);tickets--;}}}else{sellticket();}x;}}private synchronized void sellticket(){if (tickets 0) {System.out.println(Thread.currentThread().getName() 正在出售第 tickets 张票);tickets--;}}
}public class SellTicketDemo {public static void main(String[] args) {SellTicket stnew SellTicket();Thread t1new Thread(st,窗口1);Thread t2new Thread(st,窗口2);Thread t3new Thread(st,窗口3);t1.start();t2.start();t3.start();}
}5. 线程安全的类 6. Lock锁 1. 虽然我们可以理解同步代码块和同步方法的锁对象问题但是我们并没有直接看到在哪里加上了锁在哪里释放了锁为了更清晰的表达如何加锁和释放锁JDK5以后提供了一个新的锁对象Lock。 2. Lock实现提供比使用synchronized方法和语句可以获得更广泛的锁定操作。 3. Lock中获得锁和释放锁的方法void lock()获得锁。void unlock()释放锁。 4. Lock是接口不能直接实例化这里采用它的实现类ReentrantLock来实例化。 5. 代码块举例
public class SellTicket implements Runnable{//表示有100张票private int tickets100;private Lock locknew ReentrantLock();Overridepublic void run(){while (true) {lock.lock();if (tickets 0) {System.out.println(Thread.currentThread().getName() 正在出售第 tickets 张票);tickets--;}lock.unlock();}}
}public class SellTicketDemo {public static void main(String[] args) {SellTicket stnew SellTicket();Thread t1new Thread(st,窗口1);Thread t2new Thread(st,窗口2);Thread t3new Thread(st,窗口3);t1.start();t2.start();t3.start();}
}