java多线程
来源:互联网 发布:软件学报审稿流程 编辑:程序博客网 时间:2024/04/20 10:58
意义
- 提高CPU的使用率
- 提高应用程序的使用率
实现方案
- 继承Thread类
- 实现Runnable接口
调度和优先级
调度:分时调度,抢占式调度 (Java采用的是该调度方式)
优先级:范围是1-10,默认是5
生命周期
- 新建 – 就绪 – 运行 – 阻塞 – 就绪 – 运行 – 死亡
- 新建 – 就绪 – 运行 – 死亡
死锁问题
两个或两个以上的线程在争夺资源的过程中,发生的一种相互等待的现象。
public class DieLockDemo { public static void main(String[] args) { DieLock dl1 = new DieLock(true); DieLock dl2 = new DieLock(false); dl1.start(); dl2.start(); }}public class MyLock { // 创建两把锁对象 public static final Object objA = new Object(); public static final Object objB = new Object();}public class DieLock extends Thread { private boolean flag; public DieLock(boolean flag) { this.flag = flag; } @Override public void run() { if (flag) { synchronized (MyLock.objA) { System.out.println("if objA"); synchronized (MyLock.objB) { System.out.println("if objB"); } } } else { synchronized (MyLock.objB) { System.out.println("else objB"); synchronized (MyLock.objA) { System.out.println("else objA"); } } } }}
以售票为例子记录多线程下存在的问题
public class SellTicket implements Runnable { // 定义100张票 private int tickets = 100; @Override public void run() { while (true) { // t1,t2,t3三个线程 if (tickets > 0) { // 模拟 try { Thread.sleep(100); //t1进来了并休息,t2进来了并休息,t3进来了并休息, } catch (InterruptedException e) { e.printStackTrace(); } System.out.println(Thread.currentThread().getName() + "正在出售第" + (tickets--) + "张票"); //可能会出现的问题: //窗口1正在出售第100张票 //窗口2正在出售第100张票 //... //窗口1正在出售第1张票,tickets=0 //窗口2正在出售第0张票,tickets=-1 //窗口3正在出售第-1张票,tickets=-2 } } }}
上面的问题是因为线程能同时进入代码块,解决的方法是对操作共享数据的地方加锁
public class SellTicket implements Runnable { // 定义100张票 private static int tickets = 100; // 定义同一把锁 private Object obj = new Object(); //方式1:锁是唯一的任意的 @Override public void run() { while (true) { synchronized (obj) { if (tickets > 0) { try { Thread.sleep(100); } catch (InterruptedException e) { e.printStackTrace(); } System.out.println(Thread.currentThread().getName() + "正在出售第" + (tickets--) + "张票 "); } } } } @Override public void run() { while (true) { sellTicket(); } } //方式2: private void sellTicket() { synchronized (d) { if (tickets > 0) { try { Thread.sleep(100); } catch (InterruptedException e) { e.printStackTrace(); } System.out.println(Thread.currentThread().getName() + "正在出售第" + (tickets--) + "张票 "); } } } //方式3:同步加在方法上此时的锁是this private synchronized void sellTicket() { if (tickets > 0) { try { Thread.sleep(100); } catch (InterruptedException e) { e.printStackTrace(); } System.out.println(Thread.currentThread().getName() + "正在出售第" + (tickets--) + "张票 "); } } //方式4:同步加在方法上此时的锁是类字节码文件对象 private static synchronized void sellTicket() { if (tickets > 0) { try { Thread.sleep(100); } catch (InterruptedException e) { e.printStackTrace(); } System.out.println(Thread.currentThread().getName() + "正在出售第" + (tickets--) + "张票 "); } }}
生产者消费者
public class Student { private String name; private int age; private boolean flag; // 默认情况是没有数据,如果是true,说明有数据 public synchronized void set(String name, int age) { // 如果有数据,就等待 if (this.flag) { try { this.wait();3. //可以不指定时间,也可以指定时间,释放锁;等待直到get()取走 } catch (InterruptedException e) { e.printStackTrace(); } } // 1. 设置数据 this.name = name; this.age = age; // 修改标记 this.flag = true; this.notify();//提醒get()要拿数据了 } public synchronized void get() { // 如果没有数据,就等待 if (!this.flag) { try { this.wait();//4. 等待直到set()设置数据 } catch (InterruptedException e) { e.printStackTrace(); } } // 2. 获取数据 System.out.println(this.name + "---" + this.age); // 修改标记 this.flag = false; this.notify();//提醒set()要设置数据了 }}public class SetThread implements Runnable { private Student s; private int x = 0; public SetThread(Student s) { this.s = s; } @Override public void run() { while (true) { if (x % 2 == 0) { s.set("java", 30); } else { s.set("scala", 10); } x++; } }}public class GetThread implements Runnable { private Student s; public GetThread(Student s) { this.s = s; } @Override public void run() { while (true) { s.get(); } }}public class StudentDemo { public static void main(String[] args) { //创建资源 Student s = new Student(); //设置和获取的类 SetThread st = new SetThread(s); GetThread gt = new GetThread(s); //线程类 Thread t1 = new Thread(st); Thread t2 = new Thread(gt); //启动线程 t1.start(); t2.start(); }}
0 0
- 【Java多线程】多线程死锁
- Java 多线程
- java 多线程
- java多线程
- JAVA多线程
- java多线程
- JAVA多线程
- java多线程
- JAVA 多线程
- Java多线程
- java多线程
- JAVA 多线程
- Java 多线程
- Java 多线程
- java多线程
- Java 多线程
- Java多线程
- java 多线程
- Android数据存储五种方式总结
- Redis pub/sub(Publish,Subscribe)
- peU盘ud区和efi区如何共用wim文件
- Problem1
- 二叉树的遍历
- java多线程
- 性能优化之数据存储&DOM编程
- Qt之格栅布局(QGridLayout)
- 关于scanf、getchar的用法解析
- 学习总结(一)
- jzoj4064 JSOI2015 套娃 [贪心]
- 第二章回顾
- 关于如何使用枚举类的values方法!
- SylixOS CAN驱动框架之一