多线程下

单例设计模式:

保证类在内存中只有一个对象

如何保证类在内存中只有一个对象呢?

  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相关推荐

  1. 2019-06-03 Java学习日记 day24 多线程

    多线程 线程是程序执行的一台路径,一个进程中可以包含多条线程 多线程并发执行可以提高程序的效率,可以同时完成多项工作 多线程的应用背景 红蜘蛛同时共享屏幕给多个电脑 迅雷开启多条线程一起下载 QQ同时 ...

  2. 2019-06-02 Java学习日记之多线程上

    多线程程序实现的方式1: 1.继承Thread 定义类继承Tread 重写run方法 把新线程要做的事写在run方法中 创建线程对象 开启新线程,内部会自动执行run方法 package com.th ...

  3. Java学习日记1——基础认知

    Java学习日记1--基础认知 学习Java阶段,如果发现不正确的描述,还请指正! 首先附上Java相关下载链接和配置教程链接 Java相关软件工具下载地址:官方下载 Java环境配置(win10配置 ...

  4. Java学习日记-Day01

    Java学习日记-Day01 Java语言概述 比特(byte)与字节 内存 Java基础知识图解 人机交互方式 常用的DOS命令 常用快捷键 计算机编程语言介绍 第一代语言 第二代语言 第三代语言 ...

  5. 尚学堂Java学习日记Day3

    尚学堂Java学习日记Day3 第三天老师先回顾了昨天的内容我从回顾中掌握了新的知识 如下图所示 int与double计算,输出类型为double的不同结果 会把int转成double类型的,这是隐式 ...

  6. Java学习日记:UI篇(6)--谢尔宾斯基地毯图

    Java学习日记:UI篇(6)–谢尔宾斯基地毯图 引言:谢尔宾斯基地毯是数学家谢尔宾斯基提出的一个分形图形,谢尔宾斯基地毯和谢尔宾斯基三角形基本类似,不同之处在于谢尔宾斯基地毯采用的是正方形进行分形构 ...

  7. caffe学习日记--lesson5: VS下新建工程,探究Blob

    caffe学习日记--lesson5: VS下新建工程,探究Blob 在VS2013下新建工程,探究caffe的数据结构Blob,并使用.熟悉caffe 1.新建空白的控制台应用程序,添加main.c ...

  8. caffe学习日记--lesson4:windows下caffe DEMO (mnist and cifar10)

    caffe学习日记--lesson4:windows下caffe DEMO (mnist and cifar10) 1.下载数据 mnist官网:http://yann.lecun.com/exdb/ ...

  9. 【日记】Java学习日记(第63天)持续无聊更新

    前言 Youtube上EJ Media(up主)的视频我依次学完了HTML.CSS.Javascript.Jquery.觉得他教得挺好的(短小精悍),就继续学他教的JAVA.感觉EJ教的都是些语法什么 ...

最新文章

  1. Python编程基础:第四十五节 方法链Method Chaining
  2. C语言再学习 -- 标识符
  3. IO流文件的相对路径及获取系统路径方法
  4. 最后一块石头的重量II
  5. win7-64bit下基于VMware12.5安装rhel-server-6.3-i386
  6. [paper reading] CenterNet (Object as Points)
  7. [转]使用Android-Studio 开发Android 程序
  8. NoSQL之MongoDB复制集配置、数据导出导入
  9. 26. 复杂链表的复制
  10. 软件项目计划书的内容
  11. 汽车电子中的2520贴片晶振
  12. 2018年最新old男孩python全栈第九期课程-大牛编程吧-Python编程精品区-大牛编程吧
  13. 蒙特卡洛树搜索 Monte Carlo Tree Search
  14. 【机器学习基础】EM算法
  15. POJ 3264 线段树
  16. linux制作剪刀石头布游戏,C#实现剪刀石头布游戏
  17. Cleared thread-bound request context: org.apache.catalina.connector.RequestFacade问题和原因
  18. 那一扇窗——倪张根自述创业心路历程
  19. 搜狗输入法Mac版下载
  20. Python+selenium验证部分文本框内容相符即断言成功

热门文章

  1. java栈空异常_Java如何处理空堆栈异常?
  2. [Java] 蓝桥杯ALGO-63 算法训练 乘法表
  3. PAT 乙级 1029. 旧键盘(20) Java版
  4. LeetCode 22. Generate Parentheses
  5. 1032. 挖掘机技术哪家强(20)-PAT乙级真题
  6. SHELL 分析 列出当天访问次数最多的IP
  7. mysql 时间语句【集锦】
  8. 魅族Flyme5系统内置原生铃声免费下载
  9. 解决beego中同时开启http和https时,https端口占用问题
  10. Go语言开发(九)、Go语言并发编程