刘志梅201771010115.《面向对象程序设计(java)》第十六周学习总结
实验十六 线程技术
实验时间 2017-12-8
1、实验目的与要求
(1)当线程的run方法执行方法体中最后一条语句后,并经由执行return语句返回时,或者出现了在方法中没有捕获的异常时,线程将终止。
当对一个线程调用interrupt方法时,线程的中断状态将被置位。
每个线程都应该检查boolean标志,以判断线程是否被中断。
如果线程被阻塞,无法检测中断状态。
当在一个被阻塞的线程上调用interrupt方法时,阻塞调用将会被interrupt Exception异常中断。
(2) 线程的6种状态:New(新创建)、Runnable(可运行)、Bloced(被阻塞)、Waiting(等待)、Timed waiting(计时等待)、Terminated(被终止)。
当一个线程处于新创建状态时,程序还没有开始运行程序中的代码。
一旦调用start方法,线程处于runnable状态。
一个可运行的线程可能正在运行也可能没有运行,这取决于操作系统给线程提供运行的时间。
在具有多个处理器的机器上,每一个处理器运行一个线程,可以有多个线程并行运行。
当一个线程试图获取一个内部的对象锁,而该锁被其他线程持有,则该线程进入阻塞状态;当一个线程等待另一个线程通知调度器一个条件时,它自己进入等待状态;有几个方法有一个超时参数,调用它们线程进入计时等待状态。
线程被终止的原因有如下两个:因为run方法正常退出而自然死亡;因为一个没有捕获的异常终止了run方法而意外死亡。
(3) 线程属性包括:线程优先级、守护线程、线程组以及处理未捕获异常的处理器。
在JAVA程序设计语言中,每一个线程有一个优先级;默认情况下,一个线程继承它的父线程的优先级,可以用setPriority方法提高或降低任何一个线程的优先级。
优先级可以设置为在MIN_PRIORITY(在Thread的类中定义为1)与MAX_PRIORITY(定义为10)之间的任何值;NORM_PRIORITY被定义为5。
可以通过调用t.setDaemon(true);将线程转换为守护线程。
线程的run方法不能抛出任何受查异常,但是,非受查异常会导致线程终止。
线程组是一个可以统一管理的线程集合。
(4) 在大多数实际的多线程应用中,两个或两个以上的线程需要共享对同一数据的存取;如果两个线程存取相同的对象,并且每一个线程都调用了一个修改该对象状态的方法,此时这种情况称为竞争条件。
(5) 每一个Back对象都有自己的ReentrantLock对象,如果两个线程试图访问同一个Back对象,那么锁以串行方式提供服务。
锁和条件的关键之处:锁用来保护代码片段,任何时刻只能有一个线程执行被保护的代码;锁可以管理任何试图进入被保护代码段的线程;锁可以拥有一个或多个相关的条件对象;每个条件对象管理那些已经进入被保护的代码段但还不能运行的线程。
内部锁和条件存在的一些局限:不能中断一个正在试图获得锁的线程;试图获得锁时不能设定超时;每个锁仅有单一的条件,这可能是不够的。
(6)监视器的特性:监视器是只包含私有域的类;每一个监视器类的对象都有一个相关的锁;使用该锁对所有的方法进行加锁;该锁可以有任意多个相关条件。
在下述三个方面java对象不同于监视器,从而使得线程的安全性下降:域不要求必须是private;方法不要求必须是synchronized;内部锁对客户是可用的。
Volatile关键字为实例域的同步访问提供了一种免锁机制。
除非使用锁或Volatile修饰符,否则无法从多个线程安全的读取一个域。
假设对共享变量除了赋值之外并不完成其它操作,那么可以将这些共享变量声明为Volatile。
如果另一个线程也在更新largest,就可能阻止这个线程更新。
有可能因为每一个线程要等待更多的钱款存入而导致所有线程都阻塞,这样的状态被称为死锁。
(7)Swing不是线程安全的。
将线程与Swing一起使用时,必须遵守的两个简单原则:如果一个动作需要花费很长时间,在一个独立的工作器线程中做这件事不要在事件分配线程中做;除了事件分配线程,不要在任何线程中接触Swing组件。
2、实验内容和步骤
实验1:测试程序并进行代码注释。
测试程序1:
l 在elipse IDE中调试运行ThreadTest,结合程序运行结果理解程序;
l 掌握线程概念;
l 掌握用Thread的扩展类实现线程的方法;
l 利用Runnable接口改造程序,掌握用Runnable接口创建线程的方法。
class Lefthand extends Thread { public void run() { for(int i=0;i<=5;i++) { System.out.println("You are Students!"); try{ sleep(500); } catch(InterruptedException e) { System.out.println("Lefthand error.");} } } } class Righthand extends Thread { public void run() { for(int i=0;i<=5;i++) { System.out.println("I am a Teacher!"); try{ sleep(300); } catch(InterruptedException e) { System.out.println("Righthand error.");} } } } public class ThreadTest { static Lefthand left; static Righthand right; public static void main(String[] args) { left=new Lefthand(); right=new Righthand(); left.start(); right.start(); } } |
class Lefthand implements Runnable {
public void run() {
for (int i = ; i <= ; i++) {
System.out.println("You are Students!");
try {
Thread.sleep();
} // 休眠时间为500毫秒
catch (InterruptedException e)// 阻塞状态
{
System.out.println("Lefthand error.");
}
}
}
} class Righthand implements Runnable {
public void run() {
for (int i = ; i <= ; i++) {
System.out.println("I am a Teacher!");
try {
Thread.sleep();
} // 休眠时间为300毫秒
catch (InterruptedException e) {
System.out.println("Righthand error.");
} //
}
}
} public class thresdtest { private static Runnable Right; public static void main(String[] args)
{
Righthand righthand = new Righthand();
Thread right = new Thread(righthand);
right.start();
Lefthand lefthand=new Lefthand();
Thread left = new Thread(lefthand);
left.start(); }
}
修改后:
class Lefthand implements Runnable {
public void run() {
for (int i = ; i <= ; i++) {
System.out.println("You are Students!");
try {
Thread.sleep();
} // 休眠时间为500毫秒
catch (InterruptedException e)// 阻塞状态
{
System.out.println("Lefthand error.");
}
}
}
} class Righthand implements Runnable {
public void run() {
for (int i = ; i <= ; i++) {
System.out.println("I am a Teacher!");
try {
Thread.sleep();
} // 休眠时间为300毫秒
catch (InterruptedException e) {
System.out.println("Righthand error.");
} //
}
}
} public class thresdtest { private static Runnable Right; public static void main(String[] args)
{
Righthand righthand = new Righthand();
Lefthand lefthand=new Lefthand();
Thread right = new Thread(righthand);
Thread left = new Thread(lefthand);
right.start();
left.start(); }
}
测试程序2:
l 在Elipse环境下调试教材625页程序14-1、14-2 、14-3,结合程序运行结果理解程序;
l 在Elipse环境下调试教材631页程序14-4,结合程序运行结果理解程序;
l 对比两个程序,理解线程的概念和用途;
l 掌握线程创建的两种技术。
package bounceThread; import java.awt.*;
import java.awt.event.*; import javax.swing.*; /**
* 显示动画弹跳球。
* @version 1.34 2015-06-21
* @author Cay Horstmann
*/
public class BounceThread
{
public static void main(String[] args)
{
EventQueue.invokeLater(() -> {
JFrame frame = new BounceFrame();
frame.setTitle("BounceThread");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setVisible(true);
});
}
} /**
* 带有面板和按钮的框架。
*/
class BounceFrame extends JFrame
{
private BallComponent comp;
public static final int STEPS = ;
public static final int DELAY = ; /**
* 使用组件构造框架,以显示弹跳球和开始和关闭按钮
*/
public BounceFrame()
{
comp = new BallComponent();
add(comp, BorderLayout.CENTER);
JPanel buttonPanel = new JPanel();
addButton(buttonPanel, "Start", event -> addBall());
addButton(buttonPanel, "Close", event -> System.exit());
add(buttonPanel, BorderLayout.SOUTH);
pack();
} /**
* 将按钮添加到容器中。
* @param c the container
* @param title the button title
* @param listener the action listener for the button
*/
public void addButton(Container c, String title, ActionListener listener)
{
JButton button = new JButton(title);
c.add(button);
button.addActionListener(listener);
} /**
* 在画布上添加一个弹跳球,并启动一根线使其弹跳
*/
public void addBall()
{
Ball ball = new Ball();
comp.add(ball);
Runnable r = () -> {
try
{
for (int i = ; i <= STEPS; i++)
{
ball.move(comp.getBounds());
comp.repaint();
Thread.sleep(DELAY);
}
}
catch (InterruptedException e)
{
}
};
Thread t = new Thread(r);
t.start();
}
}
测试程序3:分析以下程序运行结果并理解程序。
class Race extends Thread { public static void main(String args[]) { Race[] runner=new Race[4]; for(int i=0;i<4;i++) runner[i]=new Race( ); for(int i=0;i<4;i++) runner[i].start( ); runner[1].setPriority(MIN_PRIORITY); runner[3].setPriority(MAX_PRIORITY);} public void run( ) { for(int i=0; i<1000000; i++); System.out.println(getName()+"线程的优先级是"+getPriority()+"已计算完毕!"); } } |
class Race extends Thread {//Race继承于Thread
public static void main(String args[]) {
Race[] runner=new Race[];
for(int i=;i<;i++)
runner[i]=new Race( );
for(int i=;i<;i++)
runner[i].start( );
runner[].setPriority(MIN_PRIORITY);
runner[].setPriority(MAX_PRIORITY);
}
public void run( )
{
for(int i=; i<; i++);//(;)延时作用(使后面的10与11行代码执行完)
System.out.println(getName()+"线程的优先级是"+getPriority()+"已计算完毕!");
}
}
测试程序4
l 教材642页程序模拟一个有若干账户的银行,随机地生成在这些账户之间转移钱款的交易。每一个账户有一个线程。在每一笔交易中,会从线程所服务的账户中随机转移一定数目的钱款到另一个随机账户。
l 在Elipse环境下调试教材642页程序14-5、14-6,结合程序运行结果理解程序;
package unsynch; import java.util.*; /**
* 有许多银行账户的银行。
* @version 1.30 2004-08-01
* @author Cay Horstmann
*/
public class Bank
{
private final double[] accounts; /**
*构建了银行。
* @param n账户数量
* @param 每个帐户的初始余额
*/
public Bank(int n, double initialBalance)
{
accounts = new double[n];
Arrays.fill(accounts, initialBalance);
} /**
* 把钱从一个账户转到另一个账户。
* @param 从账户转出
* @param 到账转到
* @param 转帐金额
*/
public void transfer(int from, int to, double amount)
{
if (accounts[from] < amount) return;
System.out.print(Thread.currentThread());
accounts[from] -= amount;
System.out.printf(" %10.2f from %d to %d", amount, from, to);
accounts[to] += amount;
System.out.printf(" Total Balance: %10.2f%n", getTotalBalance());
} /**
* 获取所有帐户余额的总和。
* @return 总平衡
*/
public double getTotalBalance()
{
double sum = ; for (double a : accounts)
sum += a; return sum;
} /**
* 获取银行中的帐户编号。
* @return 账户数量
*/
public int size()
{
return accounts.length;
}
}
package unsynch; /**
* 当多个线程访问一个数据结构时,这个程序显示数据损坏。
* @version 1.31 2015-06-21
* @author Cay Horstmann
*/
public class UnsynchBankTest
{
public static final int NACCOUNTS = ;
public static final double INITIAL_BALANCE = ;
public static final double MAX_AMOUNT = ;
public static final int DELAY = ; public static void main(String[] args)
{
Bank bank = new Bank(NACCOUNTS, INITIAL_BALANCE);
for (int i = ; i < NACCOUNTS; i++)
{
int fromAccount = i;
Runnable r = () -> {
try
{
while (true)
{
int toAccount = (int) (bank.size() * Math.random());
double amount = MAX_AMOUNT * Math.random();
bank.transfer(fromAccount, toAccount, amount);
Thread.sleep((int) (DELAY * Math.random()));
}
}
catch (InterruptedException e)
{
}
};
Thread t = new Thread(r);
t.start();
}
}
}
综合编程练习
编程练习1
1. 设计一个用户信息采集程序,要求如下:
(1) 用户信息输入界面如下图所示:
(2) 用户点击提交按钮时,用户输入信息显示控制台界面;
(3) 用户点击重置按钮后,清空用户已输入信息;
(4) 点击窗口关闭,程序退出。
2.创建两个线程,每个线程按顺序输出5次“你好”,每个“你好”要标明来自哪个线程及其顺序号。
3. 完善实验十五 GUI综合编程练习程序。
import java.awt.Color;
import java.awt.Dimension;
import java.awt.FlowLayout;
import java.awt.GridLayout;
import java.awt.LayoutManager;
import java.awt.Panel;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.io.BufferedReader;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.ArrayList;
import java.util.Timer;
import java.util.TimerTask; import javax.swing.BorderFactory;
import javax.swing.ButtonGroup;
import javax.swing.ButtonModel;
import javax.swing.JButton;
import javax.swing.JCheckBox;
import javax.swing.JComboBox;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JRadioButton;
import javax.swing.JTextField; public class DemoJFrame extends JFrame {
private JPanel jPanel1;
private JPanel jPanel2;
private JPanel jPanel3;
private JPanel jPanel4;
private JTextField fieldname;
private JComboBox comboBox;
private JTextField fieldadress;
private ButtonGroup bg;
private JRadioButton nan;
private JRadioButton nv;
private JCheckBox sing;
private JCheckBox dance;
private JCheckBox draw; public DemoJFrame() {
// 设置窗口大小
this.setSize(, );
// 设置可见性
this.setVisible(true);
// 设置标题
this.setTitle("编程练习一");
// 设置关闭操作
this.setDefaultCloseOperation(EXIT_ON_CLOSE);
// 设置窗口居中
WinCenter.center(this);
// 创建四个面板对象
jPanel1 = new JPanel();
setJPanel1(jPanel1);
jPanel2 = new JPanel();
setJPanel2(jPanel2);
jPanel3 = new JPanel();
setJPanel3(jPanel3);
jPanel4 = new JPanel();
setJPanel4(jPanel4);
// 设置容器的为流布局
FlowLayout flowLayout = new FlowLayout();
this.setLayout(flowLayout);
// 将四个面板添加到容器中
this.add(jPanel1);
this.add(jPanel2);
this.add(jPanel3);
this.add(jPanel4); } /*
* 设置面一
*/
private void setJPanel1(JPanel jPanel) {
// TODO 自动生成的方法存根
jPanel.setPreferredSize(new Dimension(, ));
// 给面板的布局设置为网格布局 一行4列
jPanel.setLayout(new GridLayout(, ));
JLabel name = new JLabel("姓名");
name.setSize(, );
fieldname = new JTextField("");
fieldname.setSize(, );
JLabel study = new JLabel("edcational background");
comboBox = new JComboBox();
comboBox.addItem("junior high school");
comboBox.addItem("senior high school");
comboBox.addItem("regular college course");
jPanel.add(name);
jPanel.add(fieldname);
jPanel.add(study);
jPanel.add(comboBox); } /*
* 设置面板二
*/
private void setJPanel2(JPanel jPanel) {
// TODO 自动生成的方法存根
jPanel.setPreferredSize(new Dimension(, ));
// 给面板的布局设置为网格布局 一行4列
jPanel.setLayout(new GridLayout(, ));
JLabel name = new JLabel("address");
fieldadress = new JTextField();
fieldadress.setPreferredSize(new Dimension(, ));
JLabel study = new JLabel("hobby");
JPanel selectBox = new JPanel();
selectBox.setBorder(BorderFactory.createTitledBorder(""));
selectBox.setLayout(new GridLayout(, ));
sing = new JCheckBox("sing");
dance = new JCheckBox("dance");
draw = new JCheckBox("draw");
selectBox.add(sing);
selectBox.add(dance);
selectBox.add(draw);
jPanel.add(name);
jPanel.add(fieldadress);
jPanel.add(study);
jPanel.add(selectBox);
} /*
* 设置面板三
*/
private void setJPanel3(JPanel jPanel) {
// TODO 自动生成的方法存根
jPanel.setPreferredSize(new Dimension(, ));
FlowLayout flowLayout = new FlowLayout(FlowLayout.LEFT);
jPanel.setLayout(flowLayout);
JLabel sex = new JLabel("sex");
JPanel selectBox = new JPanel();
selectBox.setBorder(BorderFactory.createTitledBorder(""));
selectBox.setLayout(new GridLayout(, ));
bg = new ButtonGroup();
nan = new JRadioButton("man");
nv = new JRadioButton("woman");
bg.add(nan);
bg.add(nv);
selectBox.add(nan);
selectBox.add(nv);
jPanel.add(sex);
jPanel.add(selectBox); } /*
* 设置面板四
*/
private void setJPanel4(JPanel jPanel) {
// TODO 自动生成的方法存根
jPanel.setPreferredSize(new Dimension(, ));
FlowLayout flowLayout = new FlowLayout(FlowLayout.CENTER, , );
jPanel.setLayout(flowLayout);
jPanel.setLayout(flowLayout);
JButton sublite = new JButton("submit");
JButton reset = new JButton("resetting");
sublite.addActionListener((e) -> valiData());
reset.addActionListener((e) -> Reset());
jPanel.add(sublite);
jPanel.add(reset);
} /*
* 提交数据
*/
private void valiData() {
// TODO 自动生成的方法存根
// 拿到数据
String name = fieldname.getText().toString().trim();
String xueli = comboBox.getSelectedItem().toString().trim();
String address = fieldadress.getText().toString().trim();
System.out.println(name);
System.out.println(xueli);
String hobbystring="";
if (sing.isSelected()) {
hobbystring+="sing ";
}
if (dance.isSelected()) {
hobbystring+="dance ";
}
if (draw.isSelected()) {
hobbystring+="draw ";
}
System.out.println(address);
if (nan.isSelected()) {
System.out.println("man");
}
if (nv.isSelected()) {
System.out.println("woman");
}
System.out.println(hobbystring);
} /*
* 重置
*/
private void Reset() {
// TODO 自动生成的方法存根
fieldadress.setText(null);
fieldname.setText(null);
comboBox.setSelectedIndex();
sing.setSelected(false);
dance.setSelected(false);
draw.setSelected(false);
bg.clearSelection();
}
}
import java.awt.EventQueue; import javax.swing.JFrame; public class Mian {
public static void main(String[] args) {
EventQueue.invokeLater(() -> {
DemoJFrame page = new DemoJFrame();
});
}
}
import java.awt.Dimension;
import java.awt.Toolkit;
import java.awt.Window; public class WinCenter {
public static void center(Window win){
Toolkit tkit = Toolkit.getDefaultToolkit();
Dimension sSize = tkit.getScreenSize();
Dimension wSize = win.getSize();
if(wSize.height > sSize.height){
wSize.height = sSize.height;
}
if(wSize.width > sSize.width){
wSize.width = sSize.width;
}
win.setLocation((sSize.width - wSize.width)/ , (sSize.height - wSize.height)/ );
}
}
package hello; public class hello {
static Lefthand left;
static Righthand right; public static void main(String[] args) {
left = new Lefthand();//创建左手线程
right = new Righthand();//创建右手线程
left.start();
right.start();//启动线程
}
}
class Lefthand extends Thread {
public void run() {
for (int i = ; i <= ; i++) {
System.out.println(i+":lefthand Hello");//输出形式
try {
sleep();//休眠300毫秒
} catch (InterruptedException e) {
System.out.println("Lefthand error.");
}
}
}
} class Righthand extends Thread {
public void run() {
for (int i = ; i <= ; i++) {
System.out.println(i+":righthand Hello");
try {
sleep();
} catch (InterruptedException e) {
System.out.println("Righthand error.");
}
}
}
}
实验总结:通过本周实验学习了什么是线程,中断线程的概念,线程的状态以及多线程;用Thread类的子类创建线程,用start()方法启动线程,用Runnable()接口实现线程等等;最后的实验编程练习通过学长的耐心讲解掌握了一些。
刘志梅201771010115.《面向对象程序设计(java)》第十六周学习总结的更多相关文章
- 201571030332 扎西平措 《面向对象程序设计Java》第八周学习总结
<面向对象程序设计Java>第八周学习总结 项目 内容 这个作业属于哪个课程 https://www.cnblogs.com/nwnu-daizh/ 这个作业的要求在哪里 https: ...
- 201771010118马昕璐《面向对象程序设计java》第八周学习总结
第一部分:理论知识学习部分 1.接口 在Java程序设计语言中,接口不是类,而是对类的一组需求描述,由常量和一组抽象方法组成.Java为了克服单继承的缺点,Java使用了接口,一个类可以实现一个或多个 ...
- 201771010134杨其菊《面向对象程序设计java》第八周学习总结
第八周学习总结 第一部分:理论知识 一.接口.lambda和内部类: Comparator与comparable接口: 1.comparable接口的方法是compareTo,只有一个参数:comp ...
- 201771010134杨其菊《面向对象程序设计java》第七周学习总结
第七周学习总结 第一部分:理论知识 1.继承是面向对象程序设计(Object Oriented Programming-OOP)中软件重用的关键技术.继承机制使用已经定义的类作为基础建立新的类定义,新 ...
- 201771010128 王玉兰《面象对象程序设计 (Java) 》第六周学习总结
---恢复内容开始--- 第一部分:基础知识总结: 1.继承 A:用已有类来构建新类的一种机制,当定义了一个新类继承一个类时,这个新类就继承了这个类的方法和域以适应新的情况: B:特点:具有层次结构. ...
- 201871010126 王亚涛《面向对象程序设计 JAVA》 第十三周学习总结
内容 这个作业属于哪个课程 https://www.cnblogs.com/nwnu-daizh/ 这个作业的要求在哪里 https://www.cnblogs.com/nwnu-daizh/p/ ...
- 201777010217-金云馨《面向对象程序设计Java》第八周学习总结
项目 内容 这个作业属于哪个课程 https://www.cnblogs.com/nwnu-daizh/ 这个作业的要求在哪里 https://www.cnblogs.com/nwnu-daizh/p ...
- 201871010126 王亚涛 《面向对象程序设计 (Java)》第十七周学习总结
内容 这个作业属于哪个课程 https://www.cnblogs.com/nwnu-daizh/ 这个作业的要求在哪里 https://www.cnblogs.com/nwnu-daizh/p/12 ...
- 马凯军201771010116《面向对象程序设计Java》第八周学习总结
一,理论知识学习部分 6.1.1 接口概念 两种含义:一,Java接口,Java语言中存在的结构,有特定的语法和结构:二,一个类所具有的方法的特征集合,是一种逻辑上的抽象.前者叫做“Java接口”,后 ...
- 周强201771010141《面向对象程序设计Java》第八周学习总结
一.理论知识学习部分 Java为了克服单继承的缺点,Java使用了接口,一个类可以实现一个或多个接口. 接口体中包含常量定义和方法定义,接口中只进行方法的声明,不提供方法的实现. 类似建立类的继承关系 ...
随机推荐
- Python第九课学习
Python第九课学习 数据结构: 深浅拷贝 集合set 函数: 概念 创建 参数 return 定义域 www.cnblogs.com/yuanchenqi/articles/5782764.htm ...
- Ubuntu 的 bash和dash的区别
什么是bash ? Bash(GNU Bourne-Again Shell)是许多Linux平台的内定Shell,事实上,还有许多传统UNIX上用的Shell,像tcsh.csh.ash.bsh.ks ...
- 日志打入kafka改造历程-我们到底能走多远系列49
方案 日志收集的方案有很多,包括各种日志过滤清洗,分析,统计,而且看起来都很高大上.本文只描述一个打入kafka的功能. 流程:app->kafka->logstash->es-&g ...
- light sdk
//请求ajax var request = function (url,method,params,cb) { var d = ajax({ url:url, type:method, data:p ...
- JS处理日期&字符串格式相互转换
之前找过一些获取系统日期以及日期&字符串格式相互转换的方式,但总体自我感觉来说还是以下的方式会更适合一些. 如有更好的方式,望大家多多赐教和交流,谢谢! 2016年曾写过一次,不过只是发了一下 ...
- K-means算法应用:图片压缩
plt.imshow(china[:,:,2]) plt.show() from sklearn.datasets import load_sample_image china=load_sample ...
- IS基础(函数片)
函数基本介绍 为什么需要函数 之所以需要函数,是因为函数可以实现对代码的复用.相同的代码,我们不需要再重复书写,只需要书写一次就足够了.函数有些时候可以看做是一个暗箱.我们不需要知道函数内部是怎么实现 ...
- postgresql 最大连接数相关
PG中有一张表记录着当前有多少连接 表名:pg_stat_activity 查询当前连接数: select count(1) from pg_stat_activity; 查询最大连接数 show m ...
- python bif
filter(过滤器): 语法: filter(function, iterable) funciton 为判断函数 iterable 为可迭代对象 ...
- Windows操作系统线程调度耍起来
Windows等常用操作系统都不是实时性操作系统,所谓不是实时性,意思是你写的程序放在这个操作系统上面运行,当程序需要睡眠2秒时,你的程序睡眠的可能不是2秒,而是2秒后能变为可调度状态,但是如果系统程 ...