JavaSE15—多线程

JavaSE15—多线程

1. 多线程简介
程序:程序是计算机指令的集合,是以文件形式存储在磁盘上的。
进程:进程是一个运行的程序,每一个进程都有其独立的内存空间和系统资源。
线程:线程是进程中的实体,一个进程可以拥有许多个线程。
一个进程中可以包含一个或多个线程,在单线程中,程序代码按调用顺序依次往下执行。通畅所说的多线程,指的是一个进程可以同时运行几个任务,每个任务由一个线程来完成。也就是说,多个线程可以同时运行,并且在一个进程内执行不同的任务。
在Java中实现多线程有两种方式:一种是继承Thread类,另一种是实现Runnable接口

线程具有生命周期,包含4个状态,分别为创建,可执行,非执行以及消亡状态。
1. 创建
当实例化一个线程对象并执行start()方法后,线程进入”可执行”状态,开始执行时,虽然多线程给用户一种同时执行的感觉,但事实上在同一时间点只有一个线程在执行,只是线程之间转换的动作很快,因此看起来好像同时在执行一样。
2. 可执行
当线程启用start()方法后,进入可执行状态,执行用户覆盖的run方法。一个线程进入可执行状态下,并不代表可以一直执行到run()结束为止。事实上它是加入次应用程序执行安排的序列中,一个处于可执行状态下的线程,实际上可能在等待处理机调度,也可能是等待某IO事件。
3. 非可执行
当线程离开可执行状态的队列中,线程即进入非可执行状态。
4. 消亡
当run()方法执行1后,线程自动消亡,当Thread类调用start()方法时,Java虚拟机自动调用它的run()方法,而当run()方法结束时,该Thread类自动终止
2. 实现多线程的两种方法
1) 通过继承Thread类创建多线程
Thread类是Java的线程类,该类的实例对象是线程对象,因此继承该类编写线程子类是实现多线程的方式之一。通过重写Thread类中的run方法,以实现用户所需要的功能,实例化所定义的Thread类,使start()方法启动线程。
语法如下:
public class ClassName extends Thread
{
public void run(){

//详细代码

}
}

Thread类的start()方法用于启动一个线程对象
实例:创建ThreadDemo类,改类继承自Thread类并重写run方法成为线程类,在主方法中创建两个鼠类的实例对象,分别设置name为小白鼠和小灰鼠,然后同时启动两个线程在控制台查看运行情况。

package qijia.si;

public class TestDemo extends Thread{
private String name = "未知";
public TestDemo(String name){
this.name = name;
}
public void run(){
while(true){
try{
System.out.println(name+":跑到前面了");
Thread.sleep((int)(Math.random()*10000));
}catch(Exception e){
e.printStackTrace();
}
}
}
public static void main(String[] args){
Thread writer1 = new TestDemo("小白鼠");
Thread writer2 = new TestDemo("小灰鼠");
writer1.start();
writer2.start();

}
}
2)通过实现Runnable接口
如果继承Thread类实现线程类有一个缺点就是无法继承其他类。这时可以通过实现Runnable接口来创建多线程类。
Runnable接口同样定义了run()方法,实现改接口的同时,必须实现接口中的run()方法。当使用Thread()方法创建线程对象时,需要为该方法传递一个实现了Runnable接口的类对象,这样创建的线程将调用那个实现了Runnable接口的类对象中的run()方法作为其运行代码。
语法:
public class Simple implements Runnable{
Simple simple = new Simple();
Thread thread = new Thread(simple);
thread.start();

}

实例:在项目中创建SimpleThread类,改类继承JFrame类实现窗体类,同时实现Runnable接口实现多线程类。通过多线程实现将窗体中的标签先由小变大,再由大变小。
package qijia.si;

import java.awt.EventQueue;
import java.net.URL;

import javax.swing.ImageIcon;
import javax.swing.JLabel;

import javax.swing.JFrame;

public class TestDemo extends JFrame implements Runnable {
final JLabel jlabel = new JLabel(); //定义标签对象
public static void main(String args[]) {
TestDemo frame = new TestDemo(); //创建本类对象
frame.setVisible(true); //设置窗体为可视
}
public TestDemo() {
super(); //调用父类构造
getContentPane().setLayout(null); //设置窗体布局
setBounds(100, 100, 193, 167); //定义窗体显示位置与大小
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); //设置窗体关闭状态
URL url = getClass().getResource("/11111222.jpg"); //定义图片地址
ImageIcon icon = new ImageIcon(url); //根据图片地址创建图片对象
Thread thread = new Thread(this); //创建线程对象
thread.start(); //启动线程
jlabel.setBounds(40, 10, 102, 111); //设置标签显示位置与大小
jlabel.setIcon(icon); //设置标签显示图片
getContentPane().add(jlabel);
}
public void run() {
while (true) { //设置无限循环
for (int i = 0; i <= 100; i++) {
jlabel.setBounds(40, 10, i, i); //设置标签大小
try {
Thread.sleep(50); //使线程休眠
} catch (InterruptedException e) {
e.printStackTrace();
}
if (i == 100) {
for (int j = 100; j >= 0; j--) {
jlabel.setBounds(40, 10, j, j);
try {
Thread.sleep(50);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
}
}
}
3. 线程控制
1) 线程的启动
执行run()方法通过调用Thread类中的start()方法来实现。
2) 线程的休眠
通过:
try{
Thread.sleep(2000);
}catch(Exception e){
e.printStackTrace();
}
来实现进程的休眠
3) 进程的停止
public class InterruptedTest implements Runnable{
private boolean isContinue = false;
public void run(){
while(true){
//省略
if(isContinue)
break;
}
}
public void setContinue(){

this.isContinue = true;

}
}

实例:创建窗体,在窗体中添加文本域控件,通过多线程机制实现向文本域中添加数字,当数字达到100时,是线程停止。
package qijia.si;

import javax.swing.JFrame;
import javax.swing.JScrollPane;
import javax.swing.JTextArea;

public class TestDemo extends JFrame implements Runnable{
JTextArea textArea;
public TestDemo(){
super();
getContentPane().setLayout(null);
setBounds(100,100,296,217);

setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
final JScrollPane scrollPane = new JScrollPane();
scrollPane.setBounds(0,0,288,183);
getContentPane().add(scrollPane);
textArea = new JTextArea();
textArea.setLineWrap(true);
scrollPane.setViewportView(textArea);
Thread thread = new Thread(this);
thread.start();
}
public void run(){
int count = 0;
while(true){
try{
Thread.sleep(100);
textArea.append(++count+" ");
if(count ==100 )
break;
}catch(Exception e){
e.printStackTrace();
}
}
}
public static void main(String[] args){
TestDemo td = new TestDemo();
td.setVisible(true);
}

}
4) 线程的优先级
在Java中线程有优先级,优先级范围从1~10,默认为5,可以使用setPriority()方法来设定线程的优先级,优先级越高,会被提前执行。
4.综合实例:
1)创建窗体,实现窗体中添加会游泳的鱼。
package qijiasi;

import java.awt.EventQueue;
import java.net.URL;

import javax.swing.ImageIcon;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;

public class TestDemo extends JFrame implements Runnable{
final JPanel jpanel = new JPanel();
final JLabel label = new JLabel();
public TestDemo(){
super();
getContentPane().setLayout(null);
setBounds(100,100,345,193);
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

jpanel.setLayout(null);
jpanel.setBounds(0,0,337,159);
getContentPane().add(jpanel);

URL url = getClass().getResource("fish.png");
ImageIcon imageicon = new ImageIcon(url);
label.setIcon(imageicon);
label.setBounds(271,47,66,60);
jpanel.add(label);
Thread thread = new Thread(this);
thread.start();
}
public void run(){
while(true){
int lx = label.getX() - 1;
if(label.getX()>jpanel.getX()){
label.setLocation(lx,label.getY());
}else{
label.setBounds(271,47,66,60);
}
try{
Thread.sleep(30);
}catch(Exception e){
e.printStackTrace();
}
}
}
public static void main(String[] args){
TestDemo td = new TestDemo();
td.setVisible(true);
}
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值