2019-06-03 Java学习日记之多线程下GUI
多线程下
单例设计模式:
保证类在内存中只有一个对象
如何保证类在内存中只有一个对象呢?
1、控制类的创建,不让其他类来创建本类的对象
2、在本类中定义一个本类的对象,Singleton s
3、提供公共的访问方式
单例写法两种:
1、饿汉式 开发用这种
2、懒汉式 面试用这种
3、第三种格式
public class Demo1 {/*** 单例设计模式:保证类在内存中只有一个对象*/public static void main(String[] args) {//Singleton s1 = new Singleton(); Singleton s1 = Singleton.s; //成员变量被私有,不能通过类名.调用 //Singleton.s = null;Singleton s2 = Singleton.s;System.out.println(s1 == s2);/*Singleton s1 = Singleton.getInstance();Singleton s2 = Singleton.getInstance();System.out.println(s1 == s2);*/} } /*** 饿汉式* @author clq*class Singleton {//1、私有构造方法,其他类不能访问该构造方法了private Singleton(){}//2、创建本类对象private static Singleton s = new Singleton();//3、对外提供公共的访问方法public static Singleton getInstance(){ //获取实例return s;}}*//*** 懒汉式,单例的延迟加载模式* @author clq**//*class Singleton {//1、私有构造方法,其他类不能访问该构造方法了private Singleton(){}//2、声明一个引用private static Singleton s;//3、对外提供公共的访问方法public static Singleton getInstance(){ //获取实例if (s == null) {//线程1等待,线程2等待s = new Singleton();}return s;}}*//*** 饿汉式和懒汉式的区别:* 1、饿汉式是空间换时间,懒汉式是时间换空间* 2、在多线程访问是,饿汉式不会创建多个对象,而懒汉式有可能会创建多个对象* */ class Singleton {//1、私有构造方法,其他类不能访问该构造方法了private Singleton(){}//2、声明一个引用public static final Singleton s = new Singleton();}
Runtime类:
Runtime类是一个单例类
import java.io.IOException;public class Demo2 {public static void main(String[] args) throws IOException {Runtime r = Runtime.getRuntime(); //获取运行时对象//r.exec("shutdown -s -t 300");r.exec("shutdown -a");}}
Timer:
Timer类:计时器
import java.util.Date; import java.util.Timer; import java.util.TimerTask;public class Demo3 {public static void main(String[] args) throws InterruptedException {Timer t = new Timer();t.schedule(new MyTimerTask(), new Date(119,5,5,9,42,50),3000);//在指定时间安排指定任务//第一个参数,是安排的任务,第二个参数是执行的时间,第三个参数是过多长时间再重复执行while(true){Thread.sleep(1000);System.out.println(new Date());}} } class MyTimerTask extends TimerTask {@Overridepublic void run() {System.out.println("我爱学习");}}
两个线程间的通信:
1、什么时候需要通信
多个线程并发执行时,在默认情况下CPU是随机切换线程的
如果我们希望他们有规律的执行,就可以使用通信,例如每个线程执行一次打印
2、怎么通信
如果希望线程等待,就调用wait()
如果希望唤醒等待的线程,就调用notify()
这两个方法必须在同步的代码中执行,并且使用同步锁对象来调用
import java.util.FormatFlagsConversionMismatchException;public class Demo4 {public static void main(String[] args) {final Printer p = new Printer();new Thread(){public void run(){while(true){try {p.print1();} catch (InterruptedException e) {e.printStackTrace();}}}}.start();new Thread(){public void run(){while(true){try {p.print2();} catch (InterruptedException e) {e.printStackTrace();}}}}.start();}} //等待唤醒机制 class Printer {private int flag = 1;public void print1() throws InterruptedException { synchronized(this){if (flag != 1) {this.wait(); //当前线程等待 }System.out.print("H");System.out.print("e");System.out.print("l");System.out.print("l");System.out.print("o");System.out.print("\r\n");flag = 2;this.notify(); //随机唤醒单个等待的线程 }}public void print2() throws InterruptedException { synchronized (this) {if (flag != 2) {this.wait();}System.out.print("酷");System.out.print("狗");System.out.print("\r\n");flag = 1;this.notify();}}}
三个或三个以上间的线程通信:
多个线程通信的问题
notify()方法是随机唤醒一个线程
notifyAll()方法是唤醒所有线程
JDK5之前无法唤醒指定的一个线程
如果多个线程之间通信,需要使用notifyAll()通知所有线程,用while来反复判断条件
public class Demo5 {public static void main(String[] args) {final Printer2 p = new Printer2();new Thread() {public void run() {while (true) {try {p.print1();} catch (InterruptedException e) {e.printStackTrace();}}}}.start();new Thread() {public void run() {while (true) {try {p.print2();} catch (InterruptedException e) {e.printStackTrace();}}}}.start();new Thread() {public void run() {while (true) {try {p.print3();} catch (InterruptedException e) {e.printStackTrace();}}}}.start();} }class Printer2 {private int flag = 1;public void print1() throws InterruptedException {synchronized (this) {while (flag != 1) {this.wait(); // 当前线程等待 }System.out.print("H");System.out.print("e");System.out.print("l");System.out.print("l");System.out.print("o");System.out.print("\r\n");flag = 2;// this.notify(); //随机唤醒单个等待的线程this.notifyAll();}}public void print2() throws InterruptedException {synchronized (this) {while (flag != 2) {this.wait(); // 线程2在此等待 }System.out.print("酷");System.out.print("狗");System.out.print("\r\n");flag = 3;// this.notify();this.notifyAll();}}public void print3() throws InterruptedException {synchronized (this) {while (flag != 3) {this.wait(); // 线程3在此等待,if语句是在哪里等待,就在哪里起来} // while循环是循环判断,每次都会判断标记System.out.print("m");System.out.print("u");System.out.print("s");System.out.print("i");System.out.print("c");System.out.print("\r\n");flag = 1;// this.notify();this.notifyAll();}}}
线程间的通信注意的问题:
1、在同步代码块中,用哪个对象锁,就用哪个对象调用wait方法
2、为什么wait方法和notify方法定义在Object这类中?
因为锁对象可以是任意对象,Object是所有的类的基类,所以wait方法和notify方法需要定义在Object这个类中
3、sleep方法和wait方法的区别?
a:sleep方法必须传入参数,参数就是时间,时间到了自动醒来
wait方法可以传入参数也可以不传入参数,传入参数就是在参数的时间结束后等待,不传入参数就是直接等待
b:sleep方法在同步函数或同步代码块中,不释放锁,睡着了也抱着锁睡
wait方法在同步函数或者同步代码块中,释放锁
JDK1.5的新特性互斥锁:
1、同步
使用ReentrantLock类的lock()和unlock()方法进行同步
2、通信
使用ReentrantLock类的newCondition()方法可以获取Condition对象
需要等待的时候使用Condition的await()方法,唤醒的时候用signal()方法
不同的线程使用不同的Condition,这样就能区分唤醒的时候找哪个线程了
import java.util.concurrent.locks.Condition; import java.util.concurrent.locks.ReentrantLock;public class Demo6 {public static void main(String[] args) {Printer3 p = new Printer3();new Thread(){public void run(){while(true){try {p.print1();} catch (InterruptedException e) {e.printStackTrace();}}}}.start();new Thread(){public void run(){while(true){try {p.print2();} catch (InterruptedException e) {e.printStackTrace();}}}}.start();new Thread(){public void run(){while(true){try {p.print3();} catch (InterruptedException e) {e.printStackTrace();}}}}.start();} } class Printer3 {private ReentrantLock r = new ReentrantLock();private Condition c1 = r.newCondition();private Condition c2 = r.newCondition();private Condition c3 = r.newCondition();private int flag = 1;public void print1() throws InterruptedException {r.lock(); //获取锁if (flag != 1) {c1.await();}System.out.print("H");System.out.print("e");System.out.print("l");System.out.print("l");System.out.print("o");System.out.print("\r\n");flag = 2;// this.notify(); //随机唤醒单个等待的线程 c2.signal();r.unlock(); //释放锁 }public void print2() throws InterruptedException {r.lock();if (flag != 2) {c2.await();}System.out.print("酷");System.out.print("狗");System.out.print("\r\n");flag = 3;// this.notify(); c3.signal();r.unlock();}public void print3() throws InterruptedException {r.lock();if (flag != 3) {c3.await();}System.out.print("m");System.out.print("u");System.out.print("s");System.out.print("i");System.out.print("c");System.out.print("\r\n");flag = 1;// this.notify(); c1.signal();r.unlock();}}
线程的五种状态:
新建,就绪,运行,阻塞,死亡
GUI
如何创建一个窗口并显示:
Graphical User Interface(图形用户接口)
package com.gui;import java.awt.Frame; import java.awt.Toolkit;public class Demo1 {public static void main(String[] args) {Frame f = new Frame("我的第一个窗口");f.setSize(400,600); //设置窗体大小 f.setLocation(500, 50); //设置窗体位置f.setIconImage(Toolkit.getDefaultToolkit().createImage("qq.png"));f.setVisible(true); //设置窗体可见 } }
布局管理器:
FlowLayout(流式布局管理器)
从左到右的顺序排列
Panel默认的布局管理器
BorderLayout(边界布局管理器)
东,南,西,北,中
Frame默认的布局管理器
GridLayout(网格布局管理器)
规则的矩阵
CardLayout(卡片布局管理器)
选项卡
GridBahLayout(网格包布局管理器)
非规则的矩阵
package com.gui;import java.awt.Button; import java.awt.FlowLayout; import java.awt.Frame; import java.awt.Toolkit;public class Demo1 {public static void main(String[] args) {Frame f = new Frame("我的第一个窗口");f.setSize(400,600); //设置窗体大小 f.setLocation(500, 50); //设置窗体位置f.setIconImage(Toolkit.getDefaultToolkit().createImage("qq.png"));Button b1 = new Button("按钮");f.add(b1);f.setLayout(new FlowLayout()); //设置布局管理器f.setVisible(true); //设置窗体可见 } }
窗体监听:
package com.gui;import java.awt.Button; import java.awt.FlowLayout; import java.awt.Frame; import java.awt.Toolkit; import java.awt.event.WindowAdapter; import java.awt.event.WindowEvent; import java.awt.event.WindowListener;public class Demo1 {public static void main(String[] args) {Frame f = new Frame("我的第一个窗口");f.setSize(400, 600); // 设置窗体大小f.setLocation(500, 50); // 设置窗体位置f.setIconImage(Toolkit.getDefaultToolkit().createImage("qq.png"));Button b1 = new Button("按钮");f.add(b1);f.setLayout(new FlowLayout()); // 设置布局管理器// f.addWindowListener(new MyWindowAdapter());f.addWindowListener(new WindowAdapter() {@Overridepublic void windowClosing(WindowEvent e) {System.exit(0);}});f.setVisible(true); // 设置窗体可见 } }
鼠标监听:
b1.addMouseListener(new MouseAdapter() {/*@Overridepublic void mouseClicked(MouseEvent e) { //单击System.exit(0);}*/@Overridepublic void mouseReleased(MouseEvent e) { //释放System.exit(0);}});
键盘监听和键盘事件:
b1.addKeyListener(new KeyAdapter() {@Overridepublic void keyReleased(KeyEvent e) {//System.exit(0);//System.out.println(e.getKeyCode());//if (e.getKeyCode() == 32) {if (e.getKeyCode() == KeyEvent.VK_SPACE) {System.exit(0);}}});
动作监听:
b2.addActionListener(new ActionListener() { //添加动作监听,应用场景就是暂停视频和播放视频 @Overridepublic void actionPerformed(ActionEvent e) {System.exit(0);}});
适配器设计模式:
a:什么是适配器
在使用监听器的时候,需要定义一个类事件监听器接口
通常接口中有多个方法,而程序中不一定所有的都用到,但又必须重写,这很繁琐
适配器简化了这些操作,我们定义监听器时只要继承适配器,然后重写需要的方法即可
b:适配器原理
适配器就是一个类,实现了监听器接口,所有抽象方法都重写了,但是方法全是空的
适配器类需要定义成抽象的,因为创建该类对象,调用空方法是没有意义的
目的就是为了简化程序员的操作,定义监听器时继承适配器,只重写需要的方法就可以了
事件处理:
事件:用户的一个操作
事件源:被操作的组件
监听器:一个自定义类的对象,实现了监听器接口,包含事件处理方法,吧监听器添加在事件源上,
当事件发生的时候虚拟机就会自动调用监听器中的事件处理方法
转载于:https://www.cnblogs.com/clqbolg/p/10974854.html
2019-06-03 Java学习日记之多线程下GUI相关推荐
- 2019-06-03 Java学习日记 day24 多线程
多线程 线程是程序执行的一台路径,一个进程中可以包含多条线程 多线程并发执行可以提高程序的效率,可以同时完成多项工作 多线程的应用背景 红蜘蛛同时共享屏幕给多个电脑 迅雷开启多条线程一起下载 QQ同时 ...
- 2019-06-02 Java学习日记之多线程上
多线程程序实现的方式1: 1.继承Thread 定义类继承Tread 重写run方法 把新线程要做的事写在run方法中 创建线程对象 开启新线程,内部会自动执行run方法 package com.th ...
- Java学习日记1——基础认知
Java学习日记1--基础认知 学习Java阶段,如果发现不正确的描述,还请指正! 首先附上Java相关下载链接和配置教程链接 Java相关软件工具下载地址:官方下载 Java环境配置(win10配置 ...
- Java学习日记-Day01
Java学习日记-Day01 Java语言概述 比特(byte)与字节 内存 Java基础知识图解 人机交互方式 常用的DOS命令 常用快捷键 计算机编程语言介绍 第一代语言 第二代语言 第三代语言 ...
- 尚学堂Java学习日记Day3
尚学堂Java学习日记Day3 第三天老师先回顾了昨天的内容我从回顾中掌握了新的知识 如下图所示 int与double计算,输出类型为double的不同结果 会把int转成double类型的,这是隐式 ...
- Java学习日记:UI篇(6)--谢尔宾斯基地毯图
Java学习日记:UI篇(6)–谢尔宾斯基地毯图 引言:谢尔宾斯基地毯是数学家谢尔宾斯基提出的一个分形图形,谢尔宾斯基地毯和谢尔宾斯基三角形基本类似,不同之处在于谢尔宾斯基地毯采用的是正方形进行分形构 ...
- caffe学习日记--lesson5: VS下新建工程,探究Blob
caffe学习日记--lesson5: VS下新建工程,探究Blob 在VS2013下新建工程,探究caffe的数据结构Blob,并使用.熟悉caffe 1.新建空白的控制台应用程序,添加main.c ...
- caffe学习日记--lesson4:windows下caffe DEMO (mnist and cifar10)
caffe学习日记--lesson4:windows下caffe DEMO (mnist and cifar10) 1.下载数据 mnist官网:http://yann.lecun.com/exdb/ ...
- 【日记】Java学习日记(第63天)持续无聊更新
前言 Youtube上EJ Media(up主)的视频我依次学完了HTML.CSS.Javascript.Jquery.觉得他教得挺好的(短小精悍),就继续学他教的JAVA.感觉EJ教的都是些语法什么 ...
最新文章
- Python编程基础:第四十五节 方法链Method Chaining
- C语言再学习 -- 标识符
- IO流文件的相对路径及获取系统路径方法
- 最后一块石头的重量II
- win7-64bit下基于VMware12.5安装rhel-server-6.3-i386
- [paper reading] CenterNet (Object as Points)
- [转]使用Android-Studio 开发Android 程序
- NoSQL之MongoDB复制集配置、数据导出导入
- 26. 复杂链表的复制
- 软件项目计划书的内容
- 汽车电子中的2520贴片晶振
- 2018年最新old男孩python全栈第九期课程-大牛编程吧-Python编程精品区-大牛编程吧
- 蒙特卡洛树搜索 Monte Carlo Tree Search
- 【机器学习基础】EM算法
- POJ 3264 线段树
- linux制作剪刀石头布游戏,C#实现剪刀石头布游戏
- Cleared thread-bound request context: org.apache.catalina.connector.RequestFacade问题和原因
- 那一扇窗——倪张根自述创业心路历程
- 搜狗输入法Mac版下载
- Python+selenium验证部分文本框内容相符即断言成功
热门文章
- java栈空异常_Java如何处理空堆栈异常?
- [Java] 蓝桥杯ALGO-63 算法训练 乘法表
- PAT 乙级 1029. 旧键盘(20) Java版
- LeetCode 22. Generate Parentheses
- 1032. 挖掘机技术哪家强(20)-PAT乙级真题
- SHELL 分析 列出当天访问次数最多的IP
- mysql 时间语句【集锦】
- 魅族Flyme5系统内置原生铃声免费下载
- 解决beego中同时开启http和https时,https端口占用问题
- Go语言开发(九)、Go语言并发编程