zoukankan      html  css  js  c++  java
  • java多线程同步

    用卖票演示同步代码块

     1 package javase;
     2 
     3 class Ticket implements Runnable{
     4     
     5     private int num = 100;
     6     
     7     private Object obj = new Object();
     8     
     9     public void run() {
    10         
    11         show();
    12     }
    13     
    14     public void show() {
    15         
    16         while(true) {
    17             
    18             try {
    19                 Thread.sleep(10);
    20             } catch (InterruptedException e) {
    21                 e.printStackTrace();
    22             }
    23             synchronized (obj) {
    24             
    25                 if(num>0)
    26                     System.out.println(Thread.currentThread().getName()+" ticket="+num--);
    27             }
    28         }
    29         
    30     }
    31     
    32 }
    33 
    34 public class ThreadDemo2 {
    35 
    36     public static void main(String[] args) {
    37         
    38         Ticket t = new Ticket();
    39         
    40         Thread t1 = new Thread(t);
    41         Thread t2 = new Thread(t);
    42         Thread t3 = new Thread(t);
    43         
    44         t1.start();
    45         t2.start();
    46         t3.start();
    47         
    48     }
    49 
    50 }

    创建三个线程对一个对象执行任务,即共用一个数据域。在执行 while(num>0)语句时,假设此时num=1,线程1进入并暂停运行。而此时num=1,线程2进入执行 num--,使得num=0输出打印。当线程1执行时,已经通过while语句的判断了,直接执行 num-- 输出打印,从而打印了0,出现错误。

    使用线程同步块,在synchronized语句中只有一个线程进入,此时synchronized会给出判断结果,阻挡其他线程进入synchronized下的代码块,也就使得while语句每次都能执行完,避免错误。

    演示同步函数

     1 class Tickets implements Runnable{
     2     
     3     private int num = 100;
     4     
     5     public void run() {
     6         while(true) {
     7             
     8             try {
     9                 Thread.sleep(10);
    10             } catch (InterruptedException e) {
    11                 e.printStackTrace();
    12             }
    13             show();
    14         
    15         }
    16     }
    17     
    18     public synchronized void show() {
    19         
    20         if(num>0)
    21             System.out.println(Thread.currentThread().getName()+" ticket="+num--);
    22     }
    23 }

    在函数上加上修饰符synchronized,使得函数变成同步函数。与同步代码块不同的是:同步代码块可以使用任意的对象作为锁,而同步函数只能使用本类的this作为锁。

    当同步函数是静态的时候,此时要保证两种同步都要使用一个锁,就可以用this.getClass()、类.class作为锁

    死锁:

     1 package javase;
     2 
     3 class LockObject{
     4     public static final Object obj1 = new Object();
     5     public static final Object obj2 = new Object();
     6 }
     7 
     8 class DeadLock implements Runnable{
     9     
    10     private boolean falg;
    11     public DeadLock(boolean falg) {
    12         this.falg = falg;
    13     }
    14     
    15     @Override
    16     public void run() {
    17         
    18         if(falg) {
    19             while(true)
    20                 synchronized (LockObject.obj1) {
    21                     System.out.println("if---obj1");
    22                     synchronized (LockObject.obj2) {
    23                         System.out.println("if---obj2");
    24                     }
    25                 }
    26             
    27         }
    28         else {
    29             while(true)
    30                 synchronized (LockObject.obj2) {
    31                     System.out.println("else---obj2");
    32                     synchronized (LockObject.obj1) {
    33                         System.out.println("else---obj1");
    34                     }
    35                 }
    36         }
    37         
    38     }
    39     
    40 }
    41 
    42 public class DeadLockTest {
    43 
    44     public static void main(String[] args) {
    45         
    46         DeadLock d1 = new DeadLock(true);
    47         DeadLock d2 = new DeadLock(false);
    48         
    49         Thread t1 = new Thread(d1);
    50         Thread t2 = new Thread(d2);
    51         
    52         t1.start();
    53         t2.start();
    54         
    55     }
    56 
    57 }

    死锁是因为两个以上的锁在互相调用,线程a进入后并没有释放当前它所使用的锁1。此时另线程b获得执行权进入,他拿到了自己的锁2后,准备进入锁1时发现锁1还在被线程a使用,而线程a发现锁2也被线程b使用了。造成互相拿着锁使得别人和自己也无法进入的现象

  • 相关阅读:
    oracle如何去除字符串中的重复字符
    MySQL的几个概念:主键,外键,索引,唯一索引
    从头学Qt Quick(3)-- 用QML写一个简单的颜色选择器
    [0x01 用Python讲解数据结构与算法] 关于数据结构和算法还有编程
    [0x00 用Python讲解数据结构与算法] 概览
    从头学Qt Quick(2)-- QML语法从一个简单的例子说起
    从头学Qt Quick(1) --体验快速构建动态效果界面
    Linux下U盘变成只读
    Qt Creator 黑色主题配置
    Qt5 从头学(2)--手动构建HelloWold
  • 原文地址:https://www.cnblogs.com/lsy-lsy/p/10907408.html
Copyright © 2011-2022 走看看