Java线程--扩展

扩展一些Java线程的知识。

首先说一下线程相关的常用类:

1. Timer:定时器、调度器、计时器。

2. TimerTask:定时任务。

下面根据这两个类写一个欢迎界面:

import java.awt.BorderLayout;

importjava.awt.CardLayout;

import java.util.Timer;

import java.util.TimerTask;

import javax.swing.ImageIcon;

import javax.swing.JFrame;

import javax.swing.JLabel;

import javax.swing.JPanel;

import com.sun.awt.AWTUtilities;

publicclassLogoextends JFrame{

privateintniIndex = 1;

private JLabel jbShow;

private Timer timer;

public Logo(){

JPanel pnBasic = new JPanel();

//设置布局为东西南北中布局

pnBasic.setLayout(new BorderLayout());

jbShow = new JLabel();

//添加图片,图片的路径可以自己设定

jbShow.setIcon(new ImageIcon("p_w_picpath\\logo\\1.png"));

//把标签添加进来吗,并放在中间的位置

pnBasic.add(jbShow,BorderLayout.CENTER);

setContentPane(pnBasic);

//下面两句是设置窗口透明

setUndecorated(true);

AWTUtilities.setWindowOpaque(this, false);

//设置标题

setTitle("欢迎界面");

//设置窗口大小

setBounds(200,200,500,400);

//设置窗口自适应

pack();

//设置推出方式

setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

//设置窗口可见

setVisible(true);

//创建定时器

timer = new Timer();

//安排指定的任务在指定的时间开始进行重复的固定延迟执行

//task - 所要安排的任务

//firstTime - 首次执行任务的时间

//period - 执行各后续任务之间的时间间隔,单位是毫秒

timer.schedule(new LogoMoniter(),1000,500);

}

privateclass LogoMoniter extends TimerTask{

@Override

publicvoid run() {

if(niIndex<7){

niIndex++;

jbShow.setIcon(new ImageIcon("p_w_picpath\\logo\\"+niIndex+".png"));

}else{

//终止此计时器,丢弃所有当前已安排的任务

timer.cancel();

//销毁窗口

dispose();

try {

Thread.sleep(2000);

} catch (InterruptedException e) {

e.printStackTrace();

}

//两秒之后再控制台输出hello

System.out.println("hello");

}

}

}

publicstaticvoid main(String[] args) {

new Logo();

}

}

这是利用定时器做的一个简单的欢迎界面。我们可以自己添加图片,注意把图片的名字命名成数字.的形式,因为我们是根据for循环来获取图片名字的。

接下来说一个Java线程中的问题,比如我们去银行存取钱,如果网络存在一点延迟,假设你的亲人就在网络延迟的时候也在存取钱,那么可能最后的余额就会出现问题,下面通过程序来具体看一下:

publicclass Bank1 {

publicstaticvoid main(String[] args) {

Account1 account = new Account1();

Person you1 = new Person(account);

Person youGF1 = new Person(account);

Thread th1 = new Thread(you1);

Thread th2 = new Thread(youGF1);

th1.start();

th2.start();

try {

Thread.sleep(4000);// 确保账户操作完毕

} catch (InterruptedException e) {

e.printStackTrace();

}

System.out.println("最终余额:" + account.balance);

}

}

class Account1 {

publicintbalance = 2000;

//取钱

publicvoid withdraw() {

int temp = balance;

temp = temp - 800;

try {

Thread.sleep(1000);

} catch (InterruptedException e) {

e.printStackTrace();

}

balance = temp;

System.out.println(Thread.currentThread().getName() + ":余额:"

+ this.balance);

}

}

class Person implements Runnable {

private Account1 account;

public Person(Account1 account) {

super();

this.account = account;

}

@Override

publicvoid run() {

account.withdraw();

}

}

这个程序完成的功能是两个人取同一个账户里的钱。

执行结果:

Thread-0:余额:1200

Thread-1:余额:1200

最终余额:1200

通过结果可以看到,没取之前余额是2000,而两个人每次取的钱都是800,正常情况余额应该是400,这就是我们所说的问题,那么应该如何解决呢?

线程间的同步:本质:把异步转化为同步,把并行转为串行。

有两种方式可以解决:

1. 同步语句块:synchronized(obj){}

2. 同步方法:在方法前加synchronized修饰符,拿到的仍然是本类对象的锁。

难点:不容易测出来。

对象锁:每个对象都有一把锁。同步锁、互斥锁。

下面通过程序看一下:

publicclass Bank1 {

publicstaticvoid main(String[] args) {

Account1 account = new Account1();

Person you1 = new Person(account);

Person youGF1 = new Person(account);

Thread th1 = new Thread(you1);

Thread th2 = new Thread(youGF1);

th1.start();

th2.start();

try {

Thread.sleep(4000);// 确保账户操作完毕

} catch (InterruptedException e) {

e.printStackTrace();

}

System.out.println("最终余额:" + account.balance);

}

}

class Account1 {

publicintbalance = 2000;

private Object obj = new Object();

// 加了一把互斥锁,只能有一个线程执行

public/*synchronized*/void withdraw() {

//两种方法

synchronized (obj) {

int temp = balance;

temp = temp - 800;

try {

Thread.sleep(1000);

} catch (InterruptedException e) {

e.printStackTrace();

}

balance = temp;

System.out.println(Thread.currentThread().getName() + ":余额:"

+ this.balance);

}

}

}

class Person implements Runnable {

private Account1 account;

public Person(Account1 account) {

super();

this.account = account;

}

@Override

publicvoid run() {

account.withdraw();

}

}

执行结果:

Thread-0:余额:1200

Thread-1:余额:400

最终余额:400

通过上面的两种方式,我们可以看到余额正常了。

转载于:https://blog.51cto.com/libaiqiang/1268748

Java线程--扩展相关推荐

  1. 面试必问---Java线程池8大拒绝策略

    前言 谈到java的线程池最熟悉的莫过于ExecutorService接口了,jdk1.5新增的java.util.concurrent包下的这个api,大大的简化了多线程代码的开发.而不论你用Fix ...

  2. Java线程怎样映射到操作系统线程

    先说多线程模型,参考经典教材<Operating System Concepts , Silberschatz ,9th edition> 中文版是<操作系统概念,第9版> h ...

  3. 2017年50道Java线程面试题

    下面是Java线程相关的热门面试题,你可以用它来好好准备面试. 1) 什么是线程? 线程是操作系统能够进行运算调度的最小单位,它被包含在进程之中,是进程中的实际运作单位.程序员可以通过它进行多处理器编 ...

  4. Java线程面试题 Top 50(转)

    不管你是新程序员还是老手,你一定在面试中遇到过有关线程的问题.Java语言一个重要的特点就是内置了对并发的支持,让Java大受企业和程序员的欢迎.大多数待遇丰厚的Java开发职位都要求开发者精通多线程 ...

  5. java线程池拒绝策略_Java核心知识 多线程并发 线程池原理(二十三)

    线程池做的工作主要是控制运行的线程的数量,处理过程中将任务放入队列,然后在线程创建后 启动这些任务,如果线程数量超过了最大数量超出数量的线程排队等候,等其它线程执行完毕, 再从队列中取出任务来执行.他 ...

  6. Java 线程池必知的8 大拒绝策略

    点击上方蓝色"程序猿DD",选择"设为星标" 回复"资源"获取独家整理的学习资料! 来源 | kailing.pub/article/ind ...

  7. 【多线程】Java线程面试题 Top 50(转载)

    Java线程面试题 Top 50 原文链接:http://www.importnew.com/12773.html 本文由 ImportNew - 李 广 翻译自 javarevisited.欢迎加入 ...

  8. JAVA线程池管理及分布式HADOOP调度框架搭建

    平时的开发中线程是个少不了的东西,比如tomcat里的servlet就是线程,没有线程我们如何提供多用户访问呢?不过很多刚开始接触线程的开发攻城师却在这个上面吃了不少苦头.怎么做一套简便的线程开发模式 ...

  9. Java 线程池框架核心代码分析--转

    原文地址:http://www.codeceo.com/article/java-thread-pool-kernal.html 前言 多线程编程中,为每个任务分配一个线程是不现实的,线程创建的开销和 ...

最新文章

  1. 局域网与网络工程课堂笔记(1)(2)
  2. java slf4j日志框架_SLF4J - 日志框架 - 类库 - Java - 代码树
  3. Mybatis字段模糊查询
  4. std::priority_queue
  5. 信息技术上册教案了解计算机,信息技术上册全册教案
  6. sql:命名管道管道程序_学习SQL:命名约定
  7. 微软电脑管家登陆微软商店 简单无打扰 支持杀毒和垃圾清理等
  8. 【1】使用分类学习APP - Classification Learner App 训练分类模型
  9. 从核酸检测平台崩盘看性能工程的范围
  10. 【Django | 开发】面试招聘网站(增加csv,excel导出企业域账号集成日志管理功能)
  11. 面试题:460道Java后端面试高频题答案版「模块九:Spring」
  12. java通过struts实现web中的文件上传
  13. http请求包与请求返回的是什么
  14. Linux运维学习路径全解析
  15. 实际参数与形式参数的区别
  16. AWS KVS(Kinesis Video Streams)之WebRTC移植编译(四)
  17. Python 修改AD账号密码(一)- 启用域控LDAPS
  18. 硕士卖房,到底是行业内卷,还是自我突破
  19. MB10F-ASEMI整流桥MB10F
  20. bq24773功能分析(中文手册翻译)

热门文章

  1. asp空间和php空间_免费ASP空间与免费PHP空间
  2. android电视怎么升级失败,智能电视升级失败,原因都在这里!
  3. 【BZOJ3238】差异,后缀数组+单调栈维护height
  4. 应用程序_构建应用程序12 条参考准则
  5. dh算法 理论依据_DH算法原理
  6. java web汽车商城_基于jsp的汽车销售商城系统
  7. vlan跨交换机 udp广播_网络交换VLAN基础入门
  8. 2017.9.26 于神之怒加强版 失败总结
  9. 【Level 08】U07 Mixed Feelings L4 Learning by heart
  10. 【英语学习】【Daily English】U14 Transportation L04 I'm going to go screen