`

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);
	}
}
分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics