文档章节

线程介绍,异步,对象锁

jacky_123
 jacky_123
发布于 2015/01/20 13:37
字数 944
阅读 26
收藏 1

Java多线程编程总结

线程基础:

当创建线程时,会为非static对象各自申请内存空间

卖票程序:

线程的优先级用1-10之间的整数表示,数值越大优先级越高,默认的优先级为5。

pupublic class Main {
 static int ticket = 10;
 static Runnable mRunnable = new Runnable() {
  @Override
  public void run() {
   // TODO Auto-generated method stub
   while (true) {
    synchronized (this) {
     if (ticket > 0) {
      try {
       Thread.sleep(1000);
       System.out.println(Thread.currentThread().getName()
         + "卖出票-->" + ticket--);
      } catch (InterruptedException e) {
       // TODO Auto-generated catch block
       e.printStackTrace();
      }
     } else {
      break;
     }
    }
   }
  }
 };
 public static void main(String[] args) {
  Thread t1 = new Thread(mRunnable, "线程, A\t");
  Thread t2 = new Thread(mRunnable, "线程, B\t");
  t1.setPriority(1);
  t2.setPriority(10);
  t1.start();
  t2.start();
 }
}

 卖票程序(两线程各自有自己的票仓库)

将ticket设为non-static

public class MyThread implements Runnable {
 int ticket = 100;
 @Override
 public void run() {
  // TODO Auto-generated method stub
  while (true) {
   synchronized (this) {
    if (ticket > 0) {
     try {
      Thread.sleep(10);
      System.out.println(Thread.currentThread().getName() + "卖出票-->" + ticket--);
     } catch (InterruptedException e) {
      // TODO Auto-generated catch block
      e.printStackTrace();
     }
    } else {
     break;
    }
   }
  }
 }
 public static void main(String[] args) {
  Runnable run1 = new MyThread();
  Runnable run2 = new MyThread();
  Thread t1 = new Thread(run1,"线程   A\t");
  Thread t2 = new Thread(run2,"线程   B\t");
  t1.start();
  t2.start();
  try {
   t1.join(); 
   System.out.println(t1.getName() + "卖完票");
   t2.join();
   System.out.println(t2.getName() + "卖完票");
  } catch (InterruptedException e) {
   // TODO Auto-generated catch block
   e.printStackTrace();
  }
 }
}

 

一个死锁案例:Java:多线程死锁

public class LockDemo implements Runnable{
 private static Object object1 = new Object();
    
    private static Object object2 = new Object();
     
    private int flag = 0;
 public static void main(String[] args) throws InterruptedException {
  LockDemo run0 = new LockDemo();
  LockDemo run1 = new LockDemo();    
        run0.flag = 1;    //here    
        run1.flag = 2;    //
        Thread thread1 = new Thread(run0);
        Thread thread2 = new Thread(run1);
        thread1.start();
        thread2.start();
    }
     
    @Override
    public void run()
    {
        System.out.println(flag);
        if (flag == 1)
        {
            synchronized (object1)
            {
                System.out.println("线程 : " + flag + "锁定obj1,休息0.5秒后锁定obj2去!");
                try
                {
                    Thread.sleep(500);
                }
                catch (Exception e)
                {
                    e.printStackTrace();
                }
                synchronized (object2)
                {
                    System.out.println("线程 : " + flag + "访问 object2");
                }
            }
        }
        if (flag == 2)
        {
            synchronized (object2)
            {
                System.out.println("线程 : " + flag + "锁定obj2,休息0.5秒后锁定obj1去!");
                try
                {
                    Thread.sleep(500);
                }
                catch (Exception e)
                {
                    e.printStackTrace();
                }
                synchronized (object1)
                {
                    System.out.println("线程 : " + flag + "访问object1");
                }
            }
        }
         
    }
}

结果:

2

线程 : 2锁定obj2,休息0.5秒后锁定obj1去!

1

线程 : 1锁定obj1,休息0.5秒后锁定obj2去!

 

对象锁、notifyAll、notify、wait

wait()方法 
在其他线程调用对象的notify或notifyAll方法前,导致当前线程等待。线程会释放掉它所占有的“锁标志”,从而使别的线程有机会抢占该锁。 
唤醒当前对象锁的等待线程使用notify或notifyAll方法,wait() 和notify()必须在synchronized函数或synchronized block中进行调用。

Calculator.java:

//计算线程  
public class Calculator extends Thread {
 private int total;
 public int getTotal() {
  return total;
 }
 public void run() {
  synchronized (this) {
   for (int i = 0; i < 10; i++) {
    total += i;
   }
   // 通知所有在此对象上等待的线程
   notifyAll();
  }
 }
}

ReaderResult.java:

public class ReaderResult extends Thread {
 Calculator c;
 public ReaderResult(Calculator c) {
  this.c = c;
 }
 public void run() {
  synchronized (c) {
   try {
    System.out.println(Thread.currentThread() + "等待计算结果。。。");
    c.wait();
   } catch (InterruptedException e) {
    e.printStackTrace();
   }
   System.out
     .println(Thread.currentThread() + "计算结果为:" + c.getTotal());
  }
 }
 public static void main(String[] args) {
  // 启动5个线程,分别获取计算结果
  Calculator calculator = new Calculator();
  for (int i = 0; i < 5; i++) {
   new ReaderResult(calculator).start();
  }
  // 启动计算线程
  calculator.start();
 }
}

结果:

Thread[Thread-1,5,main]等待计算结果。。。

Thread[Thread-2,5,main]等待计算结果。。。

Thread[Thread-3,5,main]等待计算结果。。。

Thread[Thread-5,5,main]等待计算结果。。。

Thread[Thread-4,5,main]等待计算结果。。。

Thread[Thread-1,5,main]计算结果为:45

Thread[Thread-4,5,main]计算结果为:45

Thread[Thread-5,5,main]计算结果为:45

Thread[Thread-3,5,main]计算结果为:45

Thread[Thread-2,5,main]计算结果为:45

 

 线程jion方法:等待该线程终止。等待调用join方法的线程结束,再继续执行。

public class Main {
 static class MyThread implements Runnable {
  @Override
  public void run() {
   // TODO Auto-generated method stub
   for (int i = 0; i < 5; i++) {
    try {
     Thread.sleep(1000);
     show("XIXI RUN->slower and slower");
    } catch (InterruptedException e) {
     // TODO Auto-generated catch block
     e.printStackTrace();
    }
   }
  }
 }
 public static void main(String args[]) {
  Runnable mRunnable = new MyThread();
  Thread t1 = new Thread(mRunnable, "xixi");
  t1.start();
  try {
   t1.join();
  } catch (InterruptedException e) {
   // TODO Auto-generated catch block
   e.printStackTrace();
  }
  show("MAIN RUN->CAN YOU BE FAST");
 }
 private static void show(String str) {
  System.out.println(str);
 }
}

结果:

XIXI RUN->slower and slower

XIXI RUN->slower and slower

XIXI RUN->slower and slower

XIXI RUN->slower and slower

XIXI RUN->slower and slower

MAIN RUN->CAN YOU BE FAST

© 著作权归作者所有

上一篇: android面试题
下一篇: 形参与实参
jacky_123
粉丝 3
博文 55
码字总数 26297
作品 0
南通
程序员
私信 提问
如履薄冰 —— Redis懒惰删除的巨大牺牲

之前我们介绍了Redis懒惰删除的特性,它是使用异步线程对已经删除的节点进行延后内存回收。但是还不够深入,所以本节我们要对异步线程逻辑处理的细节进行分析,看看Antirez是如何实现异步线程...

Java填坑之路
2018/08/08
0
0
【并发编程】线程安全、锁的同步和异步

一、基本概念 线程安全:当多个线程访问某一个类(对象或方法)时,这个类始终都能表现出正确的行为,那么这个类(对象或方法)就是线程安全的。 非线程安全:非线程主要是指多个线程对同一个...

qq_26545305
2018/01/22
0
0
Java编程的逻辑 -- 并发章 -- 线程的基本协作机制

线程的基本协作 线程的基本协作示例 总结 线程的基本协作 多线程间除了竞争访问同一资源外,也经常需要相互协作的去执行一些任务。而对于协作的基本机制用的最多的无疑是wait/notify。 协作的...

HikariCP
2018/06/22
0
0
全面解析Synchronized

在多线程的环境下,经常存在线程安全问题,这种问题产生的原因在于:该是原子操作的代码段被其他的线程切割,从而引起的数据混乱问题。在本篇博客中将讲述如何使用synchronized关键字保证代码...

LoveOne
2015/12/07
181
0
Lock对象锁(显式锁)第一篇实例

除了使用关键字 synchronized 支持的隐式锁(对象的内置锁)外,Concurrency API 支持由 Lock 接口指定的各种显示锁。显示锁能控制更细的粒度,因此也有更好的性能,在逻辑上也比较清晰。 标准...

hello菜bird
2018/01/18
61
0

没有更多内容

加载失败,请刷新页面

加载更多

代理模式之JDK动态代理 — “JDK Dynamic Proxy“

动态代理的原理是什么? 所谓的动态代理,他是一个代理机制,代理机制可以看作是对调用目标的一个包装,这样我们对目标代码的调用不是直接发生的,而是通过代理完成,通过代理可以有效的让调...

code-ortaerc
今天
5
0
学习记录(day05-标签操作、属性绑定、语句控制、数据绑定、事件绑定、案例用户登录)

[TOC] 1.1.1标签操作v-text&v-html v-text:会把data中绑定的数据值原样输出。 v-html:会把data中值输出,且会自动解析html代码 <!--可以将指定的内容显示到标签体中--><标签 v-text=""></......

庭前云落
今天
8
0
VMware vSphere的两种RDM磁盘

在VMware vSphere vCenter中创建虚拟机时,可以添加一种叫RDM的磁盘。 RDM - Raw Device Mapping,原始设备映射,那么,RDM磁盘是不是就可以称作为“原始设备映射磁盘”呢?这也是一种可以热...

大别阿郎
今天
12
0
【AngularJS学习笔记】02 小杂烩及学习总结

本文转载于:专业的前端网站☞【AngularJS学习笔记】02 小杂烩及学习总结 表格示例 <div ng-app="myApp" ng-controller="customersCtrl"> <table> <tr ng-repeat="x in names | orderBy ......

前端老手
昨天
16
0
Linux 内核的五大创新

在科技行业,创新这个词几乎和革命一样到处泛滥,所以很难将那些夸张的东西与真正令人振奋的东西区分开来。Linux内核被称为创新,但它又被称为现代计算中最大的奇迹,一个微观世界中的庞然大...

阮鹏
昨天
20
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部