第二十章多线程总结

2023-12-13 05:13:37

线程的特点

1.进程是资源分配的最小单位,线程是最小的执行单位

2.一个进程可以有多个线程

3.线程共享进程资源?

package twentyth;
 
 
public class ThreadTest extends Thread {
	public void run() {
		for (int i = 1; i <= 10; i++) {//继承重写方法
			System.out.print(i + " ");
		}
	}
 
	public static void main(String[] args) {
		ThreadTest t = new ThreadTest();
		t.start();
	}
}

线程的实现

package twentyth;
 
import java.awt.Container;
import javax.swing.*;
 
public class SwingAndThread extends JFrame {
	int count = 0; // 图标横坐标
 
	public SwingAndThread() {
		setBounds(300, 200, 250, 100); // 绝对定位窗体大小与位置
		Container container = getContentPane();// 主容器
		container.setLayout(null); // 使窗体不使用任何布局管理器
 
		Icon icon = new ImageIcon("src/1.gif"); // 图标对象
		JLabel jl = new JLabel(icon);// 显示图标的标签
		jl.setBounds(10, 10, 200, 50); // 设置标签的位置与大小
		Thread t = new Thread() { // 定义匿名线程对象
			public void run() {
				while (true) {
					jl.setBounds(count, 10, 200, 50); // 将标签的横坐标用变量表示
					try {
						Thread.sleep(500); // 使线程休眠500毫秒
					} catch (InterruptedException e) {
						e.printStackTrace();
					}
					count += 4; // 使横坐标每次增加4
					if (count >= 200) {
						// 当图标到达标签的最右边时,使其回到标签最左边
						count = 10;
					}
				}
			}
		};
		t.start(); // 启动线程
		container.add(jl); // 将标签添加到容器中
		setVisible(true); // 使窗体可见
		// 设置窗体的关闭方式
		setDefaultCloseOperation(EXIT_ON_CLOSE);
	}
 
	public static void main(String[] args) {
		new SwingAndThread(); // 实例化一个SwingAndThread对象
	}
}

线程的生命周期

?join线程

先运行插入线程

 
import java.awt.BorderLayout;
import javax.swing.*;
 
public class JoinTest extends JFrame {
	private Thread threadA; // 定义两个线程
	private Thread threadB;
	private JProgressBar progressBar = new JProgressBar(); // 定义两个进度条组件
	private JProgressBar progressBar2 = new JProgressBar();
 
	public static void main(String[] args) {
		JoinTest test = new JoinTest();
		test.setVisible(true);
	}
 
	public JoinTest() {
		setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
		setBounds(200, 200, 200, 100);
		getContentPane().add(progressBar, BorderLayout.NORTH); // 将进度条设置在窗体最北面
		getContentPane().add(progressBar2, BorderLayout.SOUTH); // 将进度条设置在窗体最南面
		progressBar.setStringPainted(true); // 设置进度条显示数字字符
		progressBar2.setStringPainted(true);
		// 使用匿名内部类形式初始化Thread实例
		threadA = new Thread(new Runnable() {
			int count = 0;
 
			public void run() { // 重写run()方法
				while (true) {
					progressBar.setValue(++count); // 设置进度条的当前值
					try {
						Thread.sleep(100); // 使线程A休眠100毫秒
						threadB.join(); // 使线程B调用join()方法
					} catch (InterruptedException e) {
						e.printStackTrace();
					}
				}
			}
		});
		threadA.start(); // 启动线程A
		threadB = new Thread(new Runnable() {
			int count = 0;
 
			public void run() {
				while (true) {
					progressBar2.setValue(++count); // 设置进度条的当前值
					try {
						Thread.sleep(100); // 使线程B休眠100毫秒
					} catch (InterruptedException e) {
						e.printStackTrace();
					}
					if (count == 100) // 当count变量增长为100时
						break; // 跳出循环
				}
			}
		});
		threadB.start(); // 启动线程B
	}
}

?

中断进程

如果线程是因为使用了sleep()或wait()方法进入了就绪状态,可以使用Thread类中interrupt()方法使线程离开run()方法,同时结束线程,但程序会抛出InterruptedException异常,用户可以在处理该异常时完成线程的中断业务处理,如终止while循环。

package twentyth;
import java.awt.BorderLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
 
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JProgressBar;
 
public class InterruptedSwing extends JFrame {
 
	public static void main(String[] args) {
		init(new InterruptedSwing(), 100, 100);
	}
 
	public InterruptedSwing() {
		JProgressBar progressBar = new JProgressBar(); // 创建进度条
		getContentPane().add(progressBar, BorderLayout.NORTH); // 将进度条放置在窗体合适位置
		JButton button = new JButton("停止");
		getContentPane().add(button, BorderLayout.SOUTH);
		progressBar.setStringPainted(true); // 设置进度条上显示数字
		Thread t = new Thread(new Runnable() {
			int count = 0;
 
			public void run() {
				while (true) {
					progressBar.setValue(++count); // 设置进度条的当前值
					try {
						Thread.sleep(100); // 使线程休眠100毫秒
					} catch (InterruptedException e) { // 捕捉InterruptedException异常
						System.out.println("当前线程序被中断");
						break;
					}
				}
			}
		});
 
		button.addActionListener(new ActionListener() {
 
			@Override
			public void actionPerformed(ActionEvent e) {
				t.interrupt(); // 中断线程
			}
		});
		t.start(); // 启动线程
	}
 
	public static void init(JFrame frame, int width, int height) {
		frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
		frame.setSize(width, height);
		frame.setVisible(true);
	}

?

4.线程的礼让
Thread类中提供了一种礼让方法,使用yield()方法表示,它只是给当前正处于运行状态的线程一个提醒,告知它可以将资源礼让给其他线程,但这仅是一种暗示,没有任何一种机制保证当前线程会将资源礼让。

五.线程的优先级
线程的优先级可以使用setPriority()方法调整,如果使用该方法设置的优先级不在1~10,将产生IllegalArgumentException异常。

六.线程同步

? ? ? ? 1.线程安全

例,在项目中创建ThreadSafeTest类,该类实现了Runnable接口,在未考虑到线程安全问题的基础上,模拟火车站售票系统的功能代码

代码:

?

?? 2.线程同步机制

? ? ? ? ? ? ? ? 1.同步块

Java中提供了同步机制,可以有效地防止资源冲突。同步机制使用synchronized关键字,使用该关键字包含的代码块称为同步块,也称为临界点。

? ? 2.同步方法
同步方法就是在方法前面用synchronized关键字修饰的方法,其语法如下:

synchronized void f(){}
当某个对象调用了同步方法时,该对象上的其他同步方法必须等待该同步方法执行完毕后才能被执行。必须将每个能访问共享资源的方法修饰为synchronized,否则就会出错。

文章来源:https://blog.csdn.net/XN020930/article/details/134682946
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。