实验十六 线程技术
实验时间 2017-12-8
1、实验目的与要求
(1) 掌握线程概念;
(2) 掌握线程创建的两种技术;
(3) 理解和掌握线程的优先级属性及调度方法;
(4) 掌握线程同步的概念及实现技术;
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(); } } |
1 class Lefthand extends Thread { 2 public void run() 3 { 4 for(int i=0;i<=5;i++) 5 { System.out.println("You are Students!"); 6 try{ sleep(500); }//"You are Students!"语句程序运行间隔时间为500ms 7 catch(InterruptedException e) 8 { System.out.println("Lefthand error.");} 9 } 10 } 11 } 12 class Righthand extends Thread { 13 public void run() 14 { 15 for(int i=0;i<=5;i++) 16 { System.out.println("I am a Teacher!"); 17 try{ sleep(300); }//"I am a Teacher!"语句程序运行间隔时间为300ms 18 catch(InterruptedException e) 19 { System.out.println("Righthand error.");} 20 } 21 } 22 } 23 public class ThreadTest 24 { 25 static Lefthand left; 26 static Righthand right; 27 public static void main(String[] args) 28 { 29 //创建两个线程 30 left=new Lefthand(); 31 right=new Righthand(); 32 left.start(); 33 right.start(); 34 } 35 }
1 class Lefthand implements Runnable { 2 public void run() 3 { 4 for(int i=0;i<=5;i++) 5 { System.out.println("You are Students!"); 6 try{ 7 Thread. sleep(500); 8 }//"You are Students!"语句程序运行间隔时间为500ms 9 catch(InterruptedException e) 10 { System.out.println("Lefthand error.");} 11 } 12 } 13 } 14 class Righthand implements Runnable { 15 public void run() 16 { 17 for(int i=0;i<=5;i++) 18 { System.out.println("I am a Teacher!"); 19 try{ 20 Thread.sleep(300); 21 }//"I am a Teacher!"语句程序运行间隔时间为300ms 22 catch(InterruptedException e) 23 { System.out.println("Righthand error.");} 24 } 25 } 26 } 27 public class ThreadTest 28 { 29 private static Runnable Right; 30 31 static Thread left; 32 static Thread right; 33 public static void main(String[] args) 34 { 35 //创建两个线程 36 Runnable a=new Lefthand(); 37 Runnable b=new Righthand(); 38 Thread left =new Thread(a); 39 Thread right =new Thread(b); 40 right.start(); 41 left.start(); 42 } 43 }
测试程序2:
l 在Elipse环境下调试教材625页程序14-1、14-2 、14-3,结合程序运行结果理解程序;
l 在Elipse环境下调试教材631页程序14-4,结合程序运行结果理解程序;
l 对比两个程序,理解线程的概念和用途;
l 掌握线程创建的两种技术。
1 package bounce; 2 3 import java.awt.geom.*; 4 5 /** 6 * 弹球从矩形的边缘上移动和弹出的球 7 * @version 1.33 2007-05-17 8 * @author Cay Horstmann 9 */ 10 public class Ball 11 { 12 private static final int XSIZE = 15; 13 private static final int YSIZE = 15; 14 private double x = 0; 15 private double y = 0; 16 private double dx = 1; 17 private double dy = 1; 18 19 /** 20 * 将球移动到下一个位置,如果球击中t中的一个,则向相反的方向移动。 21 */ 22 public void move(Rectangle2D bounds) 23 { 24 x += dx; 25 y += dy; 26 if (x < bounds.getMinX()) 27 { 28 x = bounds.getMinX(); 29 dx = -dx; 30 } 31 if (x + XSIZE >= bounds.getMaxX()) 32 { 33 x = bounds.getMaxX() - XSIZE; 34 dx = -dx; 35 } 36 if (y < bounds.getMinY()) 37 { 38 y = bounds.getMinY(); 39 dy = -dy; 40 } 41 if (y + YSIZE >= bounds.getMaxY()) 42 { 43 y = bounds.getMaxY() - YSIZE; 44 dy = -dy; 45 } 46 } 47 48 /** 49 * 获取当前位置的球的形状。 50 */ 51 public Ellipse2D getShape() 52 { 53 return new Ellipse2D.Double(x, y, XSIZE, YSIZE); 54 } 55 }
1 package bounce; 2 3 import java.awt.*; 4 import java.util.*; 5 import javax.swing.*; 6 7 /** 8 * 拉球的部件 9 * @version 1.34 2012-01-26 10 * @author Cay Horstmann 11 */ 12 public class BallComponent extends JPanel 13 { 14 private static final int DEFAULT_WIDTH = 450; 15 private static final int DEFAULT_HEIGHT = 350; 16 17 private java.util.List<Ball> balls = new ArrayList<>(); 18 19 /** 20 * 向组件中添加一个球 21 * @param要添加的球 22 */ 23 public void add(Ball b) 24 { 25 balls.add(b); 26 } 27 28 public void paintComponent(Graphics g) 29 { 30 super.paintComponent(g); // 擦除背景 31 Graphics2D g2 = (Graphics2D) g; 32 for (Ball b : balls) 33 { 34 g2.fill(b.getShape()); 35 } 36 } 37 38 public Dimension getPreferredSize() { return new Dimension(DEFAULT_WIDTH, DEFAULT_HEIGHT); } 39 }
1 package bounce; 2 3 import java.awt.*; 4 import java.awt.event.*; 5 import javax.swing.*; 6 7 /** 8 * 显示一个动画弹跳球 9 * @version 1.34 2015-06-21 10 * @author Cay Horstmann 11 */ 12 public class Bounce 13 { 14 public static void main(String[] args) 15 { 16 EventQueue.invokeLater(() -> { 17 JFrame frame = new BounceFrame(); 18 frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 19 frame.setVisible(true); 20 }); 21 } 22 } 23 24 /** 25 * 球组件和按钮的框架 26 */ 27 class BounceFrame extends JFrame 28 { 29 private BallComponent comp; 30 public static final int STEPS = 1000; 31 public static final int DELAY = 3; 32 33 /** 34 * 用显示弹跳球的组件和启动和关闭按钮构建框架 35 */ 36 public BounceFrame() 37 { 38 setTitle("Bounce"); 39 comp = new BallComponent(); 40 add(comp, BorderLayout.CENTER); 41 JPanel buttonPanel = new JPanel();//创建容器组件buttonPanel 42 addButton(buttonPanel, "Start", event -> addBall()); 43 addButton(buttonPanel, "Close", event -> System.exit(0)); 44 add(buttonPanel, BorderLayout.SOUTH); 45 pack(); 46 } 47 48 /** 49 * 向容器添加按钮。 50 * @param c容器 51 * @param 标题按钮标题 52 * @param 监听按钮的操作监听器 53 */ 54 public void addButton(Container c, String title, ActionListener listener) 55 { 56 JButton button = new JButton(title); 57 c.add(button); 58 button.addActionListener(listener); 59 } 60 61 /** 62 * 在面板上添加一个弹跳球,使其弹跳1000次。 63 */ 64 public void addBall() 65 { 66 try 67 { 68 Ball ball = new Ball(); 69 comp.add(ball); 70 71 for (int i = 1; i <= STEPS; i++) 72 { 73 ball.move(comp.getBounds()); 74 comp.paint(comp.getGraphics()); 75 Thread.sleep(DELAY);//Thread.sleep()需要捕捉异常,加try/catch 76 } 77 } 78 catch (InterruptedException e) 79 { 80 } 81 } 82 }
1 package bounceThread; 2 3 import java.awt.geom.*; 4 5 /** 6 弹球从矩形的边缘上移动和弹出的球 7 * @version 1.33 2007-05-17 8 * @author Cay Horstmann 9 */ 10 public class Ball 11 { 12 // private static final int XSIZE = 15; 13 // private static final int YSIZE = 15; 14 // private double x = 0; 15 // private double y = 0; 16 // private double dx = 1; 17 // private double dy = 1; 18 19 /** 20 将球移动到下一个位置,如果球击中边缘中的一个,则向相反的方向移动。 21 */ 22 public void move(Rectangle2D bounds) 23 { 24 x += dx; 25 y += dy; 26 if (x < bounds.getMinX()) 27 { 28 x = bounds.getMinX(); 29 dx = -dx; 30 } 31 if (x + XSIZE >= bounds.getMaxX()) 32 { 33 x = bounds.getMaxX() - XSIZE; 34 dx = -dx; 35 } 36 if (y < bounds.getMinY()) 37 { 38 y = bounds.getMinY(); 39 dy = -dy; 40 } 41 if (y + YSIZE >= bounds.getMaxY()) 42 { 43 y = bounds.getMaxY() - YSIZE; 44 dy = -dy; 45 } 46 } 47 48 /** 49 获取当前位置的球的形状。 50 */ 51 public Ellipse2D getShape()//把这个传给BallComponent,让BallComponent来绘制圆 52 { 53 return new Ellipse2D.Double(x, y, XSIZE, YSIZE); 54 } 55 private static final int XSIZE = 15; 56 private static final int YSIZE = 15; 57 private double x = 0; 58 private double y = 0; 59 private double dx = 1; 60 private double dy = 1; 61 }
1 package bounceThread; 2 3 import java.awt.*; 4 import java.util.*; 5 import javax.swing.*; 6 7 /** 8 * 拉球的部件 9 * @version 1.34 2012-01-26 10 * @author Cay Horstmann 11 */ 12 public class BallComponent extends JComponent 13 { 14 private static final int DEFAULT_WIDTH = 450; 15 private static final int DEFAULT_HEIGHT = 350; 16 17 private java.util.List<Ball> balls = new ArrayList<>(); 18 19 /** 20 * 在面板上添加一个球 21 * @param b为要添加的球 22 */ 23 public void add(Ball b) 24 { 25 balls.add(b); 26 } 27 28 public void paintComponent(Graphics g) 29 { 30 Graphics2D g2 = (Graphics2D) g; 31 for (Ball b : balls) 32 { 33 g2.fill(b.getShape()); 34 } 35 } 36 37 public Dimension getPreferredSize() { return new Dimension(DEFAULT_WIDTH, DEFAULT_HEIGHT); } 38 }
1 package bounceThread; 2 3 import java.awt.*; 4 import java.awt.event.*; 5 import javax.swing.*; 6 7 /** 8 * 显示动画弹跳球。 9 * @version 1.34 2015-06-21 10 * @author Cay Horstmann 11 */ 12 public class BounceThread 13 { 14 public static void main(String[] args) 15 { 16 EventQueue.invokeLater(() -> { 17 JFrame frame = new BounceFrame(); 18 frame.setTitle("BounceThread"); 19 frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 20 frame.setVisible(true); 21 }); 22 } 23 } 24 25 /** 26 * 带有面板和按钮的框架。 27 */ 28 class BounceFrame extends JFrame 29 { 30 private BallComponent comp; 31 public static final int STEPS = 1000; 32 public static final int DELAY = 5; 33 34 35 /** 36 * Constructs the frame with the component for showing the bouncing ball and 37 * Start and Close buttons 38 */ 39 public BounceFrame() 40 { 41 comp = new BallComponent(); 42 add(comp, BorderLayout.CENTER); 43 JPanel buttonPanel = new JPanel(); 44 addButton(buttonPanel, "Start", event -> addBall()); 45 addButton(buttonPanel, "Close", event -> System.exit(0)); 46 add(buttonPanel, BorderLayout.SOUTH); 47 pack(); 48 } 49 50 /** 51 *向容器添加按钮。 52 * @param c the container 53 * @param title the button title 54 * @param listener the action listener for the button 55 */ 56 public void addButton(Container c, String title, ActionListener listener) 57 { 58 JButton button = new JButton(title); 59 c.add(button); 60 button.addActionListener(listener); 61 } 62 63 /** 64 * Adds a bouncing ball to the canvas and starts a thread to make it bounce 65 */ 66 public void addBall() 67 { 68 Ball ball = new Ball(); 69 comp.add(ball);//添加并且重绘一个球 70 Runnable r = () -> { 71 try 72 { 73 for (int i = 1; i <= STEPS; i++) 74 { 75 ball.move(comp.getBounds()); 76 comp.repaint(); 77 Thread.sleep(DELAY); 78 } 79 } 80 catch (InterruptedException e) 81 { 82 } 83 }; 84 Thread t = new Thread(r); 85 t.start(); 86 } 87 }
测试程序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()+"已计算完毕!"); } } |
1 class Race extends Thread { 2 3 public static void main(String args[]) { 4 5 Race[] runner=new Race[4]; 6 7 for(int i=0;i<4;i++) runner[i]=new Race( ); 8 9 for(int i=0;i<4;i++) runner[i].start( ); 10 11 runner[1].setPriority(MIN_PRIORITY); 12 13 runner[3].setPriority(MAX_PRIORITY);} 14 15 public void run( ) { 16 17 for(int i=0; i<1000000; i++); 18 19 System.out.println(getName()+"线程的优先级是"+getPriority()+"已计算完毕!"); 20 21 } 22 23 }
测试程序4
l 教材642页程序模拟一个有若干账户的银行,随机地生成在这些账户之间转移钱款的交易。每一个账户有一个线程。在每一笔交易中,会从线程所服务的账户中随机转移一定数目的钱款到另一个随机账户。
l 在Elipse环境下调试教材642页程序14-5、14-6,结合程序运行结果理解程序;
1 package unsynch; 2 3 import java.util.*; 4 5 /** 6 * 有许多银行账户的银行。 7 * @version 1.30 2004-08-01 8 * @author Cay Horstmann 9 */ 10 public class Bank 11 { 12 private final double[] accounts; 13 14 /** 15 * 建设银行。 16 * @param 计算账号 17 * @param 每个账户的初始余额 18 */ 19 public Bank(int n, double initialBalance) 20 { 21 accounts = new double[n]; 22 Arrays.fill(accounts, initialBalance); 23 } 24 25 /** 26 * 把钱从一个账户转到另一个账户。 27 * @param 从帐户转账的参数 28 * @param 转到要转账的账户 29 * @param 转账金额 30 */ 31 public void transfer(int from, int to, double amount) 32 { 33 if (accounts[from] < amount) return; 34 System.out.print(Thread.currentThread()); 35 accounts[from] -= amount; 36 System.out.printf(" %10.2f from %d to %d", amount, from, to); 37 accounts[to] += amount; 38 System.out.printf(" Total Balance: %10.2f%n", getTotalBalance()); 39 } 40 41 /** 42 *获取所有帐户余额的总和。 43 * @return 总余额 44 */ 45 public double getTotalBalance() 46 { 47 double sum = 0; 48 49 for (double a : accounts) 50 sum += a; 51 52 return sum; 53 } 54 55 /** 56 * 获取银行中的帐户数量。 57 * @return 账号 58 */ 59 public int size() 60 { 61 return accounts.length; 62 } 63 }
1 package unsynch; 2 3 /** 4 * This program shows data corruption when multiple threads access a data structure. 5 * @version 1.31 2015-06-21 6 * @author Cay Horstmann 7 */ 8 public class UnsynchBankTest 9 { 10 public static final int NACCOUNTS = 100; 11 public static final double INITIAL_BALANCE = 1000; 12 public static final double MAX_AMOUNT = 1000; 13 public static final int DELAY = 10; 14 15 public static void main(String[] args) 16 { 17 Bank bank = new Bank(NACCOUNTS, INITIAL_BALANCE); 18 for (int i = 0; i < NACCOUNTS; i++) 19 { 20 int fromAccount = i; 21 Runnable r = () -> { 22 try 23 { 24 while (true) 25 { 26 int toAccount = (int) (bank.size() * Math.random()); 27 double amount = MAX_AMOUNT * Math.random(); 28 bank.transfer(fromAccount, toAccount, amount); 29 Thread.sleep((int) (DELAY * Math.random())); 30 } 31 } 32 catch (InterruptedException e) 33 { 34 } 35 }; 36 Thread t = new Thread(r); 37 t.start(); 38 } 39 } 40 }
综合编程练习
编程练习1
1.设计一个用户信息采集程序,要求如下:
(1) 用户信息输入界面如下图所示:
(2) 用户点击提交按钮时,用户输入信息显示控制台界面;
(3) 用户点击重置按钮后,清空用户已输入信息;
(4) 点击窗口关闭,程序退出。
1 import java.awt.Dimension; 2 import java.awt.FlowLayout; 3 import java.awt.GridLayout; 4 5 import javax.swing.BorderFactory; 6 import javax.swing.ButtonGroup; 7 import javax.swing.JButton; 8 import javax.swing.JCheckBox; 9 import javax.swing.JComboBox; 10 import javax.swing.JFrame; 11 import javax.swing.JLabel; 12 import javax.swing.JPanel; 13 import javax.swing.JRadioButton; 14 import javax.swing.JTextField; 15 16 public class DemoJFrame extends JFrame { 17 private JPanel jPanel1; 18 private JPanel jPanel2; 19 private JPanel jPanel3; 20 private JPanel jPanel4; 21 private JTextField fieldname; 22 private JComboBox comboBox; 23 private JTextField fieldadress; 24 private ButtonGroup bg; 25 private JRadioButton Male; 26 private JRadioButton Female; 27 private JCheckBox read; 28 private JCheckBox sing; 29 private JCheckBox dance; 30 31 public DemoJFrame() { 32 // 窗口大小 33 this.setSize(800, 400); 34 // 可见性 35 this.setVisible(true); 36 // 标题 37 this.setTitle("编程练习一"); 38 // 关闭操作 39 this.setDefaultCloseOperation(EXIT_ON_CLOSE); 40 // 窗口居中 41 WinCenter.center(this); 42 //四个面板对象 43 jPanel1 = new JPanel(); 44 setJPanel1(jPanel1); 45 jPanel2 = new JPanel(); 46 setJPanel2(jPanel2); 47 jPanel3 = new JPanel(); 48 setJPanel3(jPanel3); 49 jPanel4 = new JPanel(); 50 setJPanel4(jPanel4); 51 // 设置容器为流布局 52 FlowLayout flowLayout = new FlowLayout(); 53 this.setLayout(flowLayout); 54 this.add(jPanel1); 55 this.add(jPanel2); 56 this.add(jPanel3); 57 this.add(jPanel4); 58 59 } 60 61 /* 62 * 设置面板一 63 */ 64 private void setJPanel1(JPanel jPanel) { 65 66 jPanel.setPreferredSize(new Dimension(700, 45)); 67 // 给面板布局设置为网格布局 一行四列 68 jPanel.setLayout(new GridLayout(1, 4)); 69 70 JLabel name = new JLabel("name:"); 71 name.setSize(100, 50); 72 fieldname = new JTextField(""); 73 fieldname.setSize(80, 20); 74 75 JLabel study = new JLabel("qualification:"); 76 comboBox = new JComboBox(); 77 comboBox.addItem("初中"); 78 comboBox.addItem("高中"); 79 comboBox.addItem("本科"); 80 jPanel.add(name); 81 jPanel.add(fieldname); 82 jPanel.add(study); 83 jPanel.add(comboBox); 84 85 } 86 87 /* 88 * 设置面板二 89 */ 90 private void setJPanel2(JPanel jPanel) { 91 92 jPanel.setPreferredSize(new Dimension(700, 50)); 93 // 给面板的布局设置为网格布局 一行四列 94 jPanel.setLayout(new GridLayout(1, 4)); 95 96 JLabel name = new JLabel("address:"); 97 fieldadress = new JTextField(); 98 fieldadress.setPreferredSize(new Dimension(150, 50)); 99 100 JLabel study = new JLabel("hobby:"); 101 JPanel selectBox = new JPanel(); 102 selectBox.setBorder(BorderFactory.createTitledBorder("")); 103 selectBox.setLayout(new GridLayout(3, 1)); 104 read = new JCheckBox("reading"); 105 sing = new JCheckBox("singing"); 106 dance = new JCheckBox("danceing"); 107 selectBox.add(read); 108 selectBox.add(sing); 109 selectBox.add(dance); 110 jPanel.add(name); 111 jPanel.add(fieldadress); 112 jPanel.add(study); 113 jPanel.add(selectBox); 114 } 115 116 /* 117 * 设置面板三 118 */ 119 private void setJPanel3(JPanel jPanel) { 120 121 jPanel.setPreferredSize(new Dimension(700, 150)); 122 FlowLayout flowLayout = new FlowLayout(FlowLayout.LEFT); 123 jPanel.setLayout(flowLayout); 124 JLabel sex = new JLabel("性别:"); 125 JPanel selectBox = new JPanel(); 126 selectBox.setBorder(BorderFactory.createTitledBorder("")); 127 selectBox.setLayout(new GridLayout(2, 1)); 128 bg = new ButtonGroup(); 129 Male = new JRadioButton("male"); 130 Female = new JRadioButton("female"); 131 bg.add(Male ); 132 bg.add(Female); 133 selectBox.add(Male); 134 selectBox.add(Female); 135 jPanel.add(sex); 136 jPanel.add(selectBox); 137 138 } 139 140 /* 141 * 设置面板四 142 */ 143 private void setJPanel4(JPanel jPanel) { 144 145 jPanel.setPreferredSize(new Dimension(700, 150)); 146 FlowLayout flowLayout = new FlowLayout(FlowLayout.CENTER, 50, 10); 147 jPanel.setLayout(flowLayout); 148 jPanel.setLayout(flowLayout); 149 JButton sublite = new JButton("提交"); 150 JButton reset = new JButton("重置"); 151 sublite.addActionListener((e) -> valiData()); 152 reset.addActionListener((e) -> Reset()); 153 jPanel.add(sublite); 154 jPanel.add(reset); 155 } 156 157 /* 158 * 提交数据 159 */ 160 private void valiData() { 161 // 拿到数据 162 String name = fieldname.getText().toString().trim(); 163 String xueli = comboBox.getSelectedItem().toString().trim(); 164 String address = fieldadress.getText().toString().trim(); 165 System.out.println(name); 166 System.out.println(xueli); 167 String hobbystring=""; 168 if (read.isSelected()) { 169 hobbystring+="reading "; 170 } 171 if (sing.isSelected()) { 172 hobbystring+="singing "; 173 } 174 if (dance.isSelected()) { 175 hobbystring+="dancing "; 176 } 177 System.out.println(address); 178 if (Male.isSelected()) { 179 System.out.println("male"); 180 } 181 if (Female.isSelected()) { 182 System.out.println("female"); 183 } 184 System.out.println(hobbystring); 185 } 186 187 /* 188 * 重置 189 */ 190 private void Reset() { 191 fieldadress.setText(null); 192 fieldname.setText(null); 193 comboBox.setSelectedIndex(0); 194 read.setSelected(false); 195 sing.setSelected(false); 196 dance.setSelected(false); 197 bg.clearSelection(); 198 } 199 }
1 import java.awt.Dimension; 2 import java.awt.Toolkit; 3 import java.awt.Window; 4 5 public class WinCenter { 6 public static void center(Window win){ 7 Toolkit tkit = Toolkit.getDefaultToolkit(); 8 Dimension sSize = tkit.getScreenSize(); 9 Dimension wSize = win.getSize(); 10 if(wSize.height > sSize.height){ 11 wSize.height = sSize.height; 12 } 13 if(wSize.width > sSize.width){ 14 wSize.width = sSize.width; 15 } 16 win.setLocation((sSize.width - wSize.width)/ 2, (sSize.height - wSize.height)/ 2); 17 18 } 19 }
1 import java.awt.EventQueue; 2 3 import javax.swing.JFrame; 4 5 public class Project1 { 6 public static void main(String[] args) { 7 EventQueue.invokeLater(() -> { 8 DemoJFrame page = new DemoJFrame(); 9 }); 10 } 11 }
2.创建两个线程,每个线程按顺序输出5次“你好”,每个“你好”要标明来自哪个线程及其顺序号。
1 class jdi1 extends Thread { 2 public void run() 3 { 4 for(int i=1;i<=5;i++) 5 { System.out.println( i+ "Hello"+" 线程1"); 6 try{ sleep(200); } 7 catch(InterruptedException e)//异常捕获 8 { System.out.println("Lefthand error.");} 9 } 10 } 11 } 12 13 class jdi2 extends Thread { 14 public void run() 15 { 16 for(int i=1;i<=5;i++) 17 { System.out.println( i+ "你好"+" 线程2"); 18 try{ sleep(200); } 19 catch(InterruptedException e)//异常捕获 20 { System.out.println("Lefthand error.");} 21 } 22 } 23 24 } 25 public class jdi 26 { 27 static jdi1 jdi11; 28 static jdi2 jdi22; 29 public static void main(String[] args) 30 { jdi11=new jdi1(); 31 jdi22=new jdi2(); 32 //用start方法启动线程 33 jdi11.start(); 34 jdi22.start(); 35 } 36 }
总结:
本周的学习大致的了解了程序、进程和线程。
-程序 是一段静态的代码,它应用程序执行蓝 是一段静态的代码,它应用程序执行蓝 是一段静态的代码,它应用程序执行蓝 是一段静态的代码,它应用程序执行蓝本。
‐进程 是程序的一次动态执行,它对应了从代码加 是程序的一次动态执行,它对应了从代码加 是程序的一次动态执行,它对应了从代码加 是程序的一次动态执行,它对应了从代码加 载、执行至完毕的一个整过程。 载、执行至完毕的一个整过程。
‐操作系统为每个进程分配一段独立的内存空间和 操作系统为每个进程分配一段独立的内存空间和操作系统为每个进程分配一段独立的内存空间和 操作系统为每个进程分配一段独立的内存空间和 系统资源,包括:代码数据以及堆栈等。每系统资源,包括:代码数据以及堆栈等。每系统资源,包括:代码数据以及堆栈等。每系统资源,包括:代码数据以及堆栈等。每一个进程的内部数据和状态都是完全独立。 一个进程的内部数据和状态都是完全独立。 一个进程的内部数据和状态都是完全独立。 一个进程的内部数据和状态都是完全独立。
‐多任务操作系统 中,进程切换对 CPU 资源消耗较 资源消耗较 资源消耗较 资源消耗较 资源消耗较大。
多线程是进程执行过中产生的多条线索。 是进程执行过中产生的多条线索。 是进程执行过中产生的多条线索。 是进程执行过中产生的多条线索。
‐线程是比进执行更小的单位。
‐线程不能独立存在,必须于进中同一线程不能独立存在,必须于进中同一线程不能独立存在,必须于进中同一线程不能独立存在,必须于进中同一程的各线间共享进空数据。 程的各线间共享进空数据。
‐每个线程有它自身的产生、存在和消亡过, 每个线程有它自身的产生、存在和消亡过, 每个线程有它自身的产生、存在和消亡过, 每个线程有它自身的产生、存在和消亡过, 是一个动态的概念。
‐多线程意味着一个序的行语句可以看上去几多线程意味着一个序的行语句可以看上去几 多线程意味着一个序的行语句可以看上去几多线程意味着一个序的行语句可以看上去几乎在同一时间内运行。
‐线程创建、销毁和切换的负荷远小于进,又称线程创建、销毁和切换的负荷远小于进,又称线程创建、销毁和切换的负荷远小于进,又称线程创建、销毁和切换的负荷远小于进,又称为轻量级进程。
Java实现多线程的途径有两个:
1、创建 Thread 类
2、的子‐在程序中定义实现 Runnable 接
然后用创建该子类的对象
Lefthand left=new Lefthand ();
Righthand right=new Righthand ();
最后用 start() 方法启动线程
left.start ();
right.start ();
在之后的编程中会慢慢了解。