正在运行中的应用程序,通常称为进程。每个进程都有自己独立的地址空间(内存空间),每当用户启动一个进程时,操作系统就会为该进程分配一个独立的内存空间,让应用程序在这个独立的内存空间中运行。
(main函数是线程、Thread t=new Thread()。出来的是线程,正常的情况下的方法不是线程。).
线程是一个轻量级的子进程,是最小的处理单元;是一个单独的执行路径。可以说:线程是进程的子集(部分)。
线程是独立的。如果在一个线程中发生异常,则不会影响其他线程。它使用共享内存区域。
1、容易创建新线程。但是,创建新进程需要重复父进程。
2线程可以控制同一进程的其他线程**。进程无法控制兄弟进程,只能控制其子进程。
3、进程拥有自己的内存空间。线程使用进程的内存空间,且要和该进程的其他线程共享这个空间;而不是在进程中给每个线程单独划分一点空间。
4、(同一进程中的)线程在共享内存空间中运行,而进程在不同的内存空间中运行。
5、线程可以使用wait(),notify(),notifyAll()等方法直接与其他线程(同一进程)通信;而,进程需要使用“进程间通信”(IPC)来与操作系统中的其他进程通信。

多任务是指在系统中同时运行多个程序,如果只有一个处理器只有一个进程的一个指令被执行,可以使这些程序进行交替执行,由于间隔的时间短,这些程序看上去好像在同时运行.
如果将进程划分为线程,每个线程轮流占用处理器,可以减少并发时间.
为什么要创建线程?
为了将进程划分为线程,要在程序中创建多个线程对象(java.lang.Thread)



在Java中,每个程序至少自动拥有一个主线程。如果需要使用其他线程,采用以下两种方式进行创建新的线程。
第一种:
继承(Thread)类,用它覆盖类方法中的run()方法.
import java.sql.SQLOutput;
import java.util.*;
import java.awt.*;
import java.lang.Math;
public class hello extends Thread {
public void run(){
for(int i=0;i<10;i++){
System.out.println(currentThread().getName()+i);
}
}
public static void main(String []avgs) {
System.out.println(activeCount()); //当前线程活跃数目
hello h1=new hello(); //创建新线程
hello h2=new hello(); //创建新线程
h1.start(); //导入线程
h2.start(); //导入线程
//Thread.currentThread().getThreadGroup().list();
}
}

第二种:
编写一个类,使它实现java.lang.Runnable接口,然后在Thread构造函数中使用它.
import java.sql.SQLOutput;
import java.util.*;
import java.awt.*;
import java.lang.Math;
public class hello implements Runnable {
public void run(){
for(int i=0;i<10;i++){
System.out.println(Thread.currentThread().getName()+" "+i); //线程对象调用
}
}
public static void main(String []avgs) {
System.out.println(Thread.activeCount()); //当前线程活跃数目
hello h1=new hello(); //接口对象
Thread t1=new Thread(h1); //把接口得对象传递给线程
hello h2=new hello(); //接口对象
Thread t2=new Thread(h2);//把接口得对象传递给线程
t1.start(); //导入线程
t2.start(); //导入线程
//Thread.currentThread().getThreadGroup().list(); //得到调用线程的列表
}
}

创建(new)—>就绪(start)—>运行中(调度)------->死亡(run()结束)
阻塞:
1.等待阻塞: 运行中 调用(wait())函数的时候,如果调用notify()或则notifyAll() 就解除当前的阻塞进入到 就绪阶段.
2.互斥阻塞:运行中 调用synchronized()函数,试图获得某个对象的同步锁,如果该对象的同步锁已经被其他占用,则该线程被放入锁池中.
3.其他阻塞: 运行中 调用sleep()函数,join()方法
线程的优先级范围i是1~10,最低是1,最高是10,默认是5.
获得优先级:
getPriority() //用于获得线程的优先级
设置优先级
setPriority() //用于设置优先级
1.线程的调度采用占先原则
2.相同优先级的线程,有分时和独占两种调度方式.
包括了一些严重的。程序不能处理的系统错误,如同有内存不足,虚拟机错误、栈溢出等。这类错误主要由硬件问题引起的,与程序无关。
Exection类及其子类都是程序因考虑不周或不可控因素导致的错误,根据编译器是否对某类异常进行检查,Expection类分为非受检异常(运行异常)和受检异常(需要程序员处理)两种。
try{}
- 1
可能出现的异常语句块,可能有错误,也可能没有错误。当try子句中的某个语句发生异常后,产生异常对象,终止当前正在执行的语句,后面的语句将不再执行,然后抛出异常对象
catch{}
- 1
根据try{}抛出的异常对象,那么catch进行从上倒下一直捕捉异常对象,进行一直捕捉,直到找到为止
finnaly{}
- 1
无论是否异常,finnaly子句依然正常执行
try{
}
catch(异常类型1, 异常对象){
//处理类型1 (拆弹专家1)
}
catch(异常类型2, 异常对象){
//处理类型2 (拆弹专家2)
}
finally{
无论出现异常都要抛出
}
错误信息:

捕捉错误:

手动修改错误:

import java.awt.*;
import java.util.Random;
public class panel extends Panel implements Runnable {
int x=10;
int y=10;
int size=30;
int m=500;
int n=350;
int k=650;
int s=200;
int f=200;
public void paint(Graphics g) {
//绘画云朵
g.setColor(Color.LIGHT_GRAY);
g.fillOval(m,250,300,150);
g.fillOval(n,300,300,100);
g.fillOval(k,300,300,100);
//绘画月亮
Color c = new Color(255, 255, 0);
g.setColor(c);
g.fillOval(200, 200, 100, 100);
Color c1 = new Color(0, 0, 0);
g.setColor(c1);
//绘制半月
g.fillArc(s, f, 100, 100, 0, 360);
//绘画星星
Color c2 = new Color(255, 192, 203);
g.setColor(c2);
Font f = new Font("黑体", Font.BOLD, size);
g.setFont(f);
int i=0;
Random r=new Random();
while(i++<300){
x=r.nextInt(1980)+1;
y=r.nextInt(1024)+1;
g.drawString("*", x, y);}
}
public void run(){ //覆盖线程的操作
while(true){
if(n>=1980){ //云朵
n=350; //左
m=500; //中
k=650; //右
}
if(f>310){ //半月
s=200;
f=200;
}
f++;
s++;
x++;
y++;
m++;
k++;
n++;
try {
Thread.sleep(30);
}catch (Exception e){
e.printStackTrace();
}repaint();
}
}
}
主方法:
import java.sql.SQLOutput;
import java.util.*;
import java.awt.*;
import java.lang.Math;
public class hello {
public static void main(String []avgs) {
Frame f=new Frame();
f.setTitle("宝马");
f.setBackground(Color.BLACK);
f.setSize(800,800);
panel p=new panel();
f.add(p);
Thread t=new Thread(p); //添加线程
t.start();
f.setLocationRelativeTo(null);
f.setVisible(true);
System.out.println(Thread.activeCount()); //当前线程活跃数目
//Thread.currentThread().getThreadGroup().list(); //得到调用线程的列表
}
}

注意:我们在使用Thread 类的sleep()方法的时候,我们要对其进行异常处理操作,否则会报错的.
方法类:
import java.awt.*;
import java.util.Random;
public class panel extends Panel implements Runnable {
int x=100;
public void run(){
while (true){
x=x+10;
if(x>1920){
x=100;
}
try {
Thread.sleep(30);
}catch (Exception e){
e.printStackTrace();
}repaint();
}
}
public void paint(Graphics g) {
Font f=new Font("黑体",Font.BOLD ,80);
Color c=new Color(225,215,30);
g.setColor(c);
g.setFont(f);
g.drawString("你",x,250);
}
}
主类:
import java.sql.SQLOutput;
import java.util.*;
import java.awt.*;
import java.lang.Math;
public class hello {
public static void main(String []avgs) {
Frame f=new Frame();
f.setTitle("宝马");
f.setBackground(Color.BLACK);
f.setSize(1920,1080);
panel p=new panel();
f.add(p);
Thread t=new Thread(p);
t.start();
f.setLocationRelativeTo(null);
f.setVisible(true);
System.out.println(Thread.activeCount()); //当前线程活跃数目
//Thread.currentThread().getThreadGroup().list(); //得到调用线程的列表
}
}

类方法
import javax.swing.*;
import java.awt.*;
import java.util.Random;
public class panel extends Panel implements Runnable {
int x=100;
int y=100;
int att=0;
public void run(){
while (true){
//设置四个姿态:
//右墙
if(att==0){
x++;
y++;
}
//下强
if(att==1){
x--;
y++;
}if(att==2){//左墙
x--;
y--;
}if(att==3){//上强
x++;
y--;
}
if(x>733){
if(att==0){att=1;}
else{att=2;}
}
if(y>711){回弹
if(att==1){att=2;
}else{att=3;}
}
if(x<0){
if(att==2){
att=3;
}else{
att=0;
}
}
if(y<0){
if(att==3){att=0;}
else{att=1;}
}
try {
Thread.sleep(1);
}catch (Exception e){
e.printStackTrace();
}repaint();
}}
public void paint(Graphics g) {
Color c=new Color(255,0,255);
g.setColor(c);
g.fillOval(x,y,50,50);
}
}
类方法:
import java.sql.SQLOutput;
import java.util.*;
import java.awt.*;
import java.lang.Math;
public class hello {
public static void main(String []avgs) {
Frame f=new Frame();
f.setTitle("宝马");
f.setBackground(Color.BLACK);
f.setSize(800,800);
panel p=new panel();
f.add(p);
Thread t=new Thread(p);
t.start();
f.setLocationRelativeTo(null);
f.setVisible(true);
}
}

基本思路:如果要垂直降落的话,我们需要借助一个载体来帮我们储存乱序的300颗星星,首先我们呢可以想到数组的作用。数组可以帮我们用来储存元素的一系列的操作。首先我们要分析这个数组要建立在paint方法的外面因为如果放在里面,在线程的调用的同时我们的数组也会重新更新。我们的而目的是不让数组更新,所以数组必须在类外进行初始化。初始化的时候我们得想到构造函数,利用构造函数进行对数组得第一个300元素进行随机分配。然后在run函数里面对初始化得数组进行高度++程序,从而到达垂直降落的效果。
类方法:
import javax.swing.*;
import java.awt.*;
import java.util.Random;
public class panel extends Panel implements Runnable {
int []m=new int[300];
int []n=new int[300];
public panel(){ //利用构造函数进行初始化前300
for(int i=0;i<300;i++){
Random r=new Random();
int m1=r.nextInt(1920)+1;
int n1=r.nextInt(1080)+1;
m[i]=m1;n[i]=n1;
}
}
public void run(){
while(true){
for(int i=0;i<300;i++) {
n[i]++;
if(n[i]==1080){
n[i]=0;
}
}
try {
Thread.sleep(10);
} catch (Exception e) {
throw new RuntimeException(e);
}repaint();
}
}
public void paint(Graphics g){
Font f1 = new Font("黑体", Font.BOLD, 30);
Random r = new Random();
int m1=r.nextInt(255)+1;
int m2=r.nextInt(255)+1;
int m3=r.nextInt(255)+1;
g.setFont(f1);
Color c = new Color(m1, m2, m3);
g.setColor(c);
for (int i=0;i<300;i++) { //绘制300个星星
g.drawString("*", m[i], n[i]);
}
}
}
主方法:
import java.sql.SQLOutput;
import java.util.*;
import java.awt.*;
import java.lang.Math;
public class hello {
public static void main(String[] avgs) {
Frame f=new Frame("小球的撞击效果示范图");
f.setSize(1920,1080);
f.setBackground(Color.black);
f.setLocationRelativeTo(null);
panel p=new panel();
f.add(p);
Thread t=new Thread(p);
t.start();
f.setVisible(true);
}
}
