2000字范文,分享全网优秀范文,学习好帮手!
2000字范文 > 高级API快速入门之多线程01【07】

高级API快速入门之多线程01【07】

时间:2021-11-02 22:08:07

相关推荐

高级API快速入门之多线程01【07】

一、概念

1. 进程与线程

a. 进程---就是正在进行的程序。

CPU在某一时间段只处理一个程序。程序也是一个进程,当程序结束,进程消失。

b. 线程---就是程序中的一个执行路径(控制单元)

线程在控制着进程的执行; 它是真正的执行者。

进程与线程的关系:一个进程中至少包含有一个或多个线程。

得到当前线程名:

System.out.println(Thread.currentThread().getName());

2. 多线程存在的意义

多线程可以让我们的程序部分可以产生同时运行的效果,各玩各的。提高效率是其次,主要是能让多段代码同时执行。

3. 多线程的目的:

为了最大限度的利用CPU资源。

4. 线程调度:

按照特定的机制为多个线程分配CPU的使用权。

调度的模式有两种:

(1) 分时调度:所有线程轮流获得CPU使用权,并平均分配每个线程占用CPU的时间;

(2) 抢占式调度:根据线程的优先级别来获取CPU的使用权。

JVM的线程调度模式采用了抢占式模式。

二、线程创建方式一:继承Thread类

关键词:Thread、run()、start()

1. Thread类创建,分两种写法:

步骤:

第1步:定义类继承Thread类;

第2步:子类中重写Thread类中的run()方法;

第3步:调用线程的start()方法

写法一:

子类:-------------------------------------------------public class Person extends Thread{@overriadpublic void run(){System.out.println("这是个线程");}}测试类:------------------------------------------------Person ps=new Person(); //初始化线程ps.start(); //启动线程并调用run方法

写法二:

测试类:------------------------------------------------new Thread(){@overriadpublic void run(){System.out.println("这是个线程");}}.start();

1.重写run方法的目的:将自定义的代码存储在run方法中,让线程运行(也就是将同时要运行的代码写在run()方法中)。

2. 通过对象.run()调用,不用start()方法调用也可以,但run()就变成主线程中的方法,与线程没关系。因为线程没有开启,你只执行了调用。

3. run()方法中仅仅是封装多线程运行的代码,而start()则是开启多线程的钥匙

4. start()方法是开启多线程,并执行run()方法。

5. 多线程的一个特性:随机性(谁抢到谁执行,至于执行多长,CPU说了算)

package javaadvan_07;//QQ程序public class Demo_02 {public static void main(String[] args) {//线程的核心:随机,灵活。//获取当前程序中的main线程for(int i=1;i<=1000;i++) {System.out.println("当前程序的main线程"+Thread.currentThread().getName());}//当前程序还需要多个线程来执行运行//实例化MyThread mt = new MyThread();//调用start方法来启动线程mt.start();//run方法与start方法的区别//run方法只是用来封装多线程执行的步骤(代码实现)//start是用来开启线程的钥匙MyThread mt = new MyThread();//调用start方法来启动线程//设置线程的优先级别 1 510mt.setPriority(Thread.MIN_PRIORITY);mt.start();MyThread mt2 = new MyThread();//调用start方法来启动线程mt2.start();}}

三、线程的操作

1. 获取线程的名字

Thread.currentThread().getName();

2. 设置线程优先级

(1)每个线程都有一个优先级;

(2)高优先级线程的执行优先于低优先级线程;

(3)每个线程都可以或不可以标记为一个守护程序。

(4)当某个线程中运行的代码创建一个新 Thread 对象时,该新线程的初始优先级被设定为创建线程的优先级,并且当且仅当创建线程是守护线程时,新线程才是守护程序。

setDaemon(true)

标识将该线程设置为后台线程,或者叫守护线程,或者叫精灵线程

例:对象.setDaemon(true)

setPriority()

设置的优先级一定要足够长时间才会有效果

例:对象.setPriority(Thread.MAX_PRIORITY); //设置最高级别10对象.setPriority(Thread.MIN_PRIORITY); //最低级别1对象.setPriority(Thread.NORM_PRIORITY); //值为5

注意:

(1)设置线程优先级的代码,要放在.start()前面。

(2)优先级高不一定代表该线程就先抢到执行权,理论是是可以,但实际情况不一样。

四、线程的状态

||===> 阻塞(临时状态)||(有执行资格,没执行权)||start() || sleep(time)新建 ========> 运行 =============> 冻结(睡眠|等待)|| wait()/notify()stop() ||||消亡(真死了)

1.新建:刚new出来在内存中

2.就绪:start表示该线程有资格抢CPU!

3.运行:抢到了CPU,会执行run方法

4.冻结:放弃了执行资格,醒了获得执行资格,但不一定马上执行。

4.死亡:执行完run方法

5.阻塞:调用了sleep方法或其他阻塞的方法

执行资格与执行权

① 没执行资格的情况下,是冻结状态;

② 有执行资格的是临时状态;

③ 既有执行资格又有执行权的是运行状态。

package javaadvan_07;/*** 下载图片的线程* @author Administrator**/public class ImgThread extends Thread{private String imgPath;public ImgThread(String imgPath) {this.imgPath = imgPath;}@Overridepublic void run() {try {WebImageLoader.imgLoad(imgPath);} catch (Exception e) {}}}package javaadvan_07;public class Demo_03 {public static void main(String[] args) {ImgThread it1 = new ImgThread("/up/7b/60/c7/7b60c7c967c06ab52bc9e2da0f4cbcbc.jpg");it1.start();ImgThread it2 = new ImgThread("//1009/1009011724789.jpg");it2.start();ImgThread it3 = new ImgThread("/up/c8/1c/2f/c81c2fe4af5222ff81f81e8f74e2ac26.jpg");it3.start();}}

五、创建线程的第二种方式:实现Runnable接口

步骤:

1. 创建类实现Runnable接口;

2. 重写Runnable接口中的run()方法;

将线程要运行的代码存放在该run方法中。

3. 通过Thread类建立线程对象;

4. 将Runnable接口的子类对象作为实际参数传递给Thread类的构造方法;

5. 调用Thread类的start方法开启线程并调用Runnable接口子类的run方法。

public class Ticket implement Runnable{private int tick=100;@overridepublic void run(){while(true){if(tick>0){System.out.println(Thread.currentThread().getName()+" sale..."+ tick--);}}}public class TickDemo{public static void main(String[] args){Ticket t=new Ticket(); //先实例化一个卖票的对象//实例化四个线程Thread t1=new Thread(t); //创建线程Thread t2=new Thread(t);Thread t3=new Thread(t);Thread t4=new Thread(t);//让四个线程开始工作t1.start(); //执行线程启动run()t2.start();t3.start();t4.start();}}

六、多线程的安全性

1. 问题:

当多条语句在操作同一个线程共享数据时,一个线程对多条语句时执行了一部分,还没有执行完,另一个线程参与进来执行。导致了共享数据的错误。

2. 解决办法:

对多条操作共享数据的语句,只能让一个线程执行完。在执行过程中,其他线程不可以参与执行。

Java对于多线程的安全问题提供了专业的解决办法:同步。

同步分:同步代码块、同步方法

锁旗标(同步):synchronized

(1) 同步代码块:synchronized(对象){ //需要被同步的代码}//表示该段代码上锁//如果是代码块后面要放上锁旗标,如果修饰方法,那么它的锁旗标是隐含的this。(2)锁旗标也可以修饰方法----同步方法。

七、利用线程实现小游戏

老虎机小游戏:

package com.zking.files_07;import java.awt.event.ActionEvent;import java.awt.event.ActionListener;import javax.swing.ImageIcon;import javax.swing.JButton;import javax.swing.JFrame;import javax.swing.JLabel;import javax.swing.JPanel;public class LFJGame extends JFrame{ImageIcon iia=new ImageIcon("image\\1.png");ImageIcon iib=new ImageIcon("image\\2.png");ImageIcon iic=new ImageIcon("image\\3.png");JLabel jla=new JLabel(iia);JLabel jlb=new JLabel(iib);JLabel jlc=new JLabel(iic);JLabel jld=new JLabel(iia);JLabel jle=new JLabel(iib);JLabel jlf=new JLabel(iic);JLabel jlg=new JLabel(iia);JLabel jlh=new JLabel(iib);JButton jba=new JButton("开始");JButton jbb=new JButton("结束");boolean flag=true;public LFJGame() {this.setTitle("老虎机");this.setSize(420, 450);this.setDefaultCloseOperation(3);this.setLocationRelativeTo(null);JPanel jpa=new JPanel();jpa.setLayout(null);jla.setBounds(20, 20, 87, 87);jpa.add(jla);jlb.setBounds(150, 20, 87, 87);jpa.add(jlb);jlc.setBounds(280, 20, 87, 87);jpa.add(jlc);jld.setBounds(20, 150, 87, 87);jpa.add(jld);jle.setBounds(20, 290, 87, 87);jpa.add(jle);jlf.setBounds(150, 290, 87, 87);jpa.add(jlf);jlg.setBounds(280, 150, 87, 87);jpa.add(jlg);jlh.setBounds(280, 290, 87, 87);jpa.add(jlh);jba.setBounds(115, 170, 70, 30);jpa.add(jba);jbb.setBounds(195, 170, 70, 30);jpa.add(jbb);jba.addActionListener(new ActionListener() {@Overridepublic void actionPerformed(ActionEvent e) {//1.点击变图//int a1= (int) (Math.random()*6+1);//int a2= (int) (Math.random()*6+1);//int a3= (int) (Math.random()*6+1);////iia=new ImageIcon("image\\"+a1+".png");//iib=new ImageIcon("image\\"+a2+".png");//iic=new ImageIcon("image\\"+a3+".png");////jla.setIcon(iia);//jlb.setIcon(iib);//jlc.setIcon(iic);//2.动起来flag=true;new Thread() {public void run() {while (flag) {/*int a1= (int) (Math.random()*6+1);int a2= (int) (Math.random()*6+1);int a3= (int) (Math.random()*6+1);iia=new ImageIcon("image\\"+a1+".png");iib=new ImageIcon("image\\"+a2+".png");iic=new ImageIcon("image\\"+a3+".png");jla.setIcon(iia);jlb.setIcon(iib);jlc.setIcon(iic);*///优化代码ht(jla,iia);ht(jlb,iib);ht(jlc,iic);ht(jld,iia);ht(jle,iib);ht(jlf,iic);ht(jlg,iia);ht(jlh,iib);try {Thread.sleep(100);} catch (InterruptedException e) {// TODO Auto-generated catch blocke.printStackTrace();}}};}.start();}});//结束jbb.addActionListener(new ActionListener() {@Overridepublic void actionPerformed(ActionEvent e) {flag=false;}});this.getContentPane().add(jpa);this.setVisible(true); }//换图public void ht(JLabel jl,ImageIcon ii) {int a1= (int) (Math.random()*6+1);ii=new ImageIcon("image\\"+a1+".png");jl.setIcon(ii);}public static void main(String[] args) {new LFJGame();}}

飞天猪小游戏:

package com.zking.files_07;import java.awt.event.KeyEvent;import java.awt.event.KeyListener;import javax.swing.ImageIcon;import javax.swing.JFrame;import javax.swing.JLabel;import javax.swing.JPanel;public class ZhuZhu extends JFrame{private JPanel jpa = new JPanel(null);private ImageIcon image = new ImageIcon("image\\bj.gif");private JLabel jla = new JLabel(image);private ImageIcon imb = new ImageIcon("image\\zz.gif");private JLabel jlb = new JLabel(imb);private JLabel jlc = new JLabel(new ImageIcon("image\\zd.gif"));public ZhuZhu() {this.setTitle("");this.setSize(820,320);this.setDefaultCloseOperation(3);this.setLocationRelativeTo(null);jla.setBounds(0, 0,820, 320);jpa.add(jla);jlb.setBounds(670,160,96,96);jla.add(jlb);jlc.setBounds(680, 180, 78, 78);jla.add(jlc);this.addKeyListener(new KeyListener() {@Overridepublic void keyTyped(KeyEvent e) {char keyChar = e.getKeyChar();if(keyChar == 'a') {jlb.setLocation(jlb.getX()-10, jlb.getY());}else if(keyChar == 'd') {jlb.setLocation(jlb.getX()+10, jlb.getY());}else if(keyChar == 'w') {jlb.setLocation(jlb.getX(), jlb.getY()-10);}else if(keyChar == 's') {jlb.setLocation(jlb.getX(), jlb.getY()+10);}}@Overridepublic void keyReleased(KeyEvent e) {//System.out.println("按键释压");}@Overridepublic void keyPressed(KeyEvent e) {//System.out.println("按键获压");}});this.getContentPane().add(jpa);this.setVisible(true);}public static void main(String[] args) {new ZhuZhu();}}

简单游戏:

package com.zking.files_07;import java.awt.Image;import java.awt.event.KeyEvent;import java.awt.event.KeyListener;import javax.swing.ImageIcon;import javax.swing.JFrame;import javax.swing.JLabel;import javax.swing.JOptionPane;import javax.swing.JPanel;public class MyGame extends JFrame{private JPanel jpa = new JPanel(null);private JLabel jla = new JLabel(new ImageIcon("image\\1.png"));private JLabel jlb = new JLabel(new ImageIcon("image\\2.png"));private JLabel jlc = new JLabel(new ImageIcon("image\\3.png"));boolean f = true;public MyGame() {this.setTitle("游戏机");this.setSize(841, 350);this.setDefaultCloseOperation(3);this.setLocationRelativeTo(null);jla.setBounds(630, 140, 78, 78);jlb.setBounds(20, 140, 78, 78);jlc.setBounds(650, 250, 78, 78);jpa.add(jla);jpa.add(jlb);jlc.setVisible(false);jpa.add(jlc);new Thread() {public void run() {f = true;while(f) {try {Thread.sleep(50);} catch (InterruptedException e) {// TODO Auto-generated catch blocke.printStackTrace();}if(jlb.getY()+128 <= 300) {//System.out.println(jlb.getY());jlb.setLocation(jlb.getX(), jlb.getY()+5);}else {f = false;}}};}.start();if(f == false) {new Thread() {public void run() {while(true) {if(jlb.getY()+128 >= 300) {jlb.setLocation(jlb.getX(), jlb.getY()-5);}if(jlb.getY()+128 < 10) {f = true;break;}}};}.start();}this.addKeyListener(new KeyListener() {@Overridepublic void keyTyped(KeyEvent e) {char keyChar = e.getKeyChar();if('A' == keyChar) {//System.out.println(keyChar);//子弹显示jlc.setVisible(true);new Thread() {public void run() {while(true) {try {Thread.sleep(100);} catch (InterruptedException e) {// TODO Auto-generated catch blocke.printStackTrace();}jlc.setLocation(jlc.getX()-10, jlc.getY());if(jlc.getX() == jlb.getX()) {JOptionPane.showMessageDialog(null, "GAME over");break;}}};}.start();}}@Overridepublic void keyReleased(KeyEvent e) {// TODO Auto-generated method stub}@Overridepublic void keyPressed(KeyEvent e) {// TODO Auto-generated method stub}});this.getContentPane().add(jpa);this.setVisible(true);}public static void main(String[] args) {new MyGame();}}

简单实现点名器:

package com.zking.files_07;import java.awt.Font;import java.awt.event.ActionEvent;import java.awt.event.ActionListener;import java.util.Random;import javax.swing.JButton;import javax.swing.JFrame;import javax.swing.JLabel;import javax.swing.JPanel;public class DianMingQi extends JFrame {private JPanel jpa = new JPanel(null);private JLabel jla = new JLabel("芝麻馅的汤圆0");private JButton jba = new JButton("开始");private JButton jbb = new JButton("终止");private String [] mz = {"芝麻馅的汤圆1","芝麻馅的汤圆2","芝麻馅的汤圆3","芝麻馅的汤圆4","芝麻馅的汤圆5","芝麻馅的汤圆6","芝麻馅的汤圆7","芝麻馅的汤圆8","芝麻馅的汤圆9"};private boolean flag = true;private int timer = 50;public DianMingQi() {this.setTitle("点名器");this.setSize(820, 350);this.setDefaultCloseOperation(3);this.setLocationRelativeTo(null);jla.setBounds(270, 30, 400, 100);jla.setFont(new Font("华文楷体", Font.BOLD, 45));jpa.add(jla);jba.setBounds(290, 180, 100, 50);jba.setFont(new Font("华文楷体", Font.BOLD, 27));jpa.add(jba);jbb.setBounds(430, 180, 100, 50);jbb.setFont(new Font("华文楷体", Font.BOLD, 27));jpa.add(jbb);this.getContentPane().add(jpa);jba.addActionListener(new ActionListener() {@Overridepublic void actionPerformed(ActionEvent e) {flag = true;new Thread() {public void run() {while(flag) {try {Thread.sleep(200);} catch (Exception e2) {// TODO: handle exception}Random rd = new Random();int sj = rd.nextInt(9); jla.setText(mz[sj]);timer+=5;if(timer >= 300) {timer = 50;break;}}};}.start();}});jbb.addActionListener(new ActionListener() {@Overridepublic void actionPerformed(ActionEvent e) {// TODO Auto-generated method stubflag = false;}});this.setVisible(true);}public static void main(String[] args) {new DianMingQi();}}

本内容不代表本网观点和政治立场,如有侵犯你的权益请联系我们处理。
网友评论
网友评论仅供其表达个人看法,并不表明网站立场。