📄 71.txt
字号:
//
线程是一个程序内部的顺序控制流。
线程和进程
每个进程都有独立的代码和数据空间(进程上下文),进程切换的开销大。
线程: 轻量的进程,同一类线程共享代码和数据空间,每个线程有独立的运行栈和程序计数器(PC),线程切换的开销小。
多进程: 在操作系统中能同时运行多个任务(程序)
多线程: 在同一应用程序中有多个顺序流同时执行
//
Java的线程是通过java.lang.Thread类来实现的。
每个线程都是通过某个特定Thread对象所对应的方法run( )来完成其操作的,方法run( )称为线程体。
//
创建线程 ----通过实现Runnable接口
Java中引入线程机制的目的在于实现多线程
可以使用同一个Runnable接口(的实现类)类型的实例构造多个线程
多线程之间可以共享代码和数据
举例
Thread t1 = new Thread(r);
Thread t2 = new Thread(r);
使用start() 方法启动线程
启动线程是使线程进入到可运行(runnable)状态,并不一定立即开始执行该线程
//
方 法 功 能
isAlive() 判断线程是否还“活”着,即线程是否还未终止。
getPriority() 获得线程的优先级数值
setPriority() 设置线程的优先级数值
Thread.sleep() 将当前线程睡眠指定毫秒数
join() 调用某线程的该方法,将当前线程与该线程“合并”,即等待该线程结束,再恢复当前线程的运行。
yield() 让出CPU,当前线程进入就绪队列等待调度。
wait() 当前线程进入对象的wait pool。
notify()/notifyAll() 唤醒对象的wait pool中的一个/所有等待线程。
//
使用Runnable接口
可以将CPU,代码和数据分开,形成清晰的模型;
还可以从其他类继承;
保持程序风格的一致性。
直接继承Thread类
不能再从其他类继承;
编写简单,可以直接操纵线程,无需使用Thread.currentThread()。
//
线程的调度
Java提供一个线程调度器来监控程序中启动后进入就绪状态的所有线程。线程调度器按照线程的优先级决定应调度哪些线程来执行。
setPriority(int)方法设置优先级
多数线程的调度是抢先式的。
时间片方式
非时间片方式
下面几种情况下,当前线程会放弃CPU:
线程调用了yield(),suspend()或sleep()方法主动放弃;
由于当前线程进行I/O访问,外存读写,等待用户输入等操作,导致线程阻塞;
为等候一个条件变量,线程调用wait()方法;
抢先式系统下,有高优先级的线程参与调度;时间片方式下,当前时间片用完,有同优先级的线程参与调度。
//
线程的优先级
线程的优先级用数字来表示,范围从1到10,一个线程的缺省优先级是5
Thread.MIN_PRIORITY = 1
Thread.MAX_PRIORITY = 10
Thread.NORM_PRIORITY = 5
使用下述线方法获得或设置线程对象的优先级
int getPriority();
void setPriority(int newPriority);
//
互斥锁
在Java语言中,引入了对象互斥锁的概念,来保证共享数据操作的完整性。
每个对象都对应于一个可称为“互斥锁”的标记,这个标记用来保证在任一时刻,只能有一个线程访问该对象。
关键字synchronized 来与对象的互斥锁联系。当某个对象用synchronized修饰时,表明该对象在任一时刻只能由一个线程访问。
//
//多线程编程
//创建一个基于GUI的Java程序,以多线程的方式同时显示三个不同时区的时间
import javax.swing.*;
import java.awt.*;
import java.awt.event.*;
import java.lang.*;
import java.util.*;
import java.net.*;
import java.io.*;
public class MulThreadTest
{
public static void main(String[] args)
{
ThreadFrame frame = new ThreadFrame();
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setLocation(200,100);
frame.setVisible(true);
frame.setResizable(false);
frame.addWindowListener(new
WindowAdapter()
{
public void windowClosing(WindowEvent e)
{
System.exit(0);
}
});
}
}
class ThreadFrame extends JFrame // 界面
{
public ThreadFrame()
{
this.setSize(WIDTH, HEIGHT);
this.setTitle("...show time of the world ... ");
Container contenPane = getContentPane();
JTextField[] time = new JTextField[3];
JLabel[] label = new JLabel[3];
JPanel panel = new JPanel();
for(int i=0;i<3;i++)
{
label[i] = new JLabel();
time[i] = new JTextField(18);
panel.add(label[i]);
panel.add(time[i]);
}
label[0].setText("格林尼治时间");
label[1].setText("北京时间 ");
label[2].setText("夏威夷时间 ");
JButton stop = new JButton("exit");
stop.addActionListener(new
ActionListener()
{
public void actionPerformed(ActionEvent event)
{
flag = false;
System.exit(1);
}
});
panel.add(stop);
contenPane.add(panel,BorderLayout.CENTER);
showTime[] r = new showTime[3];
Thread [] t = new Thread [3];
for(int i=0;i<3;i++)
{
r[i] = new showTime(time[i],i);
t[i] = new Thread(r[i]);
t[i].start();
}
}
public static final int WIDTH = 300;
public static final int HEIGHT = 150;
public static boolean flag = true;
}
class showTime implements Runnable // thread
{
private JTextField time;
private int timeArea;
public showTime(JTextField t,int n)
{
time = t;
timeArea = n;
}
public void run()
{
while(ThreadFrame.flag)
{
Date peiking =new Date();
if(timeArea==0) // 0 时区 格林尼治时间;
{
long l =peiking.getTime()-8*60*60*1000;
Date greenwish = new Date(l);
time.setText(greenwish.toString());
}
if(timeArea==1) // 东 8 区 北京时间
{
time.setText(peiking.toString());
}
if(timeArea==2) // 西 8 区 夏威夷时间
{
long l =peiking.getTime()-16*60*60*1000;
Date canada = new Date(l);
time.setText(canada.toString());
}
try
{
Thread.sleep(1000);
}catch(InterruptedException e)
{
e.printStackTrace();
}
}
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -