首先理解一下程序、进程、线程的具体解释
程序(program):是为完成特定任务、用某种语言编写的一组指令的集合。即指一段静态的代码,静态对象。
进程(process):是程序的一次执行过程,或是正在运行的一个程序。动态过程:有它自身的产生、存在和消亡的过程。
如:运行中的QQ,运行中的MP3播放器
程序是静态的,进程是动态的
线程(thread):进程可进一步细化为线程,是一个程序内部的一条执行路径
若一个程序可同一时间执行多个线程,就是支持多线程的
废话不多说;看看我看完视频后写的例子
创建线程的第一种方法
package com.ligang.com;
import javax.swing.text.StyledEditorKit.ForegroundAction;
/*
* 创建线程的第一种方法 继承Thread类并重写其中的run()方法
*/
public class ThreadTest {
public static void main(String[] args) {
new Thread(){//用内部内实现 重写run()方法,求1-100的奇数和偶数
@Override
public void run() {
for(int i=0;i<=100;i++){
if(i%2==0){
System.out.println(Thread.currentThread().getName()+"::::"+i+"偶数");
}//currentThread():表示当前线程 getName():表示当前线程的名字
}
}
}.start();//最后调用start方法
new Thread(){
public void run() {
for(int i=0;i<=100;i++){
if(i%2!=0){
System.out.println(Thread.currentThread().getName()+"::::"+i+"奇数");
}
}
}
}.start();
}
}
创建线程的第二种方法并实现了如何控制同步进程的第二种方法
package com.ligang.com;
import java.text.BreakIterator;
/*
* 多线程的第二种方式,实现runnable接口
* 相比于继承的方式实现多线程,runnable有可以多实现与共用同一个资源的优点
* 同步的第二種方式同步塊方法:public void synchronized +方法名{}
*/
class windows implements Runnable{//实现runnable接口
int x=100;//共享的数据
public void run() {//重写run方法
while(true){
world();
}
}
public synchronized void world(){//设置进程代码同步块:这里也会调用代码监视器,
//只不过他是隐式的调用自己本身的对象作为代码监视器
if (x > 0) {
try {
Thread.currentThread().sleep(10);//让他休息一下
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println(Thread.currentThread().getName() + "还剩票数:" + x--);
}
}
}
public class RunnablTset {
public static void main(String[] args) {
windows w1=new windows();//只需要创建一次线程,接下来便可以多次调用
Thread t1=new Thread(w1);
Thread t2=new Thread(w1);
t1.setName("子线程2:");//设置线程的名字
t2.setName("子线程3:");
t1.start();
t2.start();
}
}
用synchronized的方式来实现代码的同步
package com.ligang.com;
import java.text.BreakIterator;
/*
* 定义两个线程实现两个窗口同时卖票的模拟
* 用继承方式实现的多线程控制其安全性
* 也是用synchronized的方式来实现代码的同步,synchronized()中的代码监视器不能用this了
* 因为继承的时候创建了三个对象,所以每次都会使用自己的代码监视器,
* 从而没有解决代码同步的问题
*/
public class ThreadTest2 {
static int x=100;//假设有一百张票,让两个线程一起卖这一百张票,所以一定要把票数加static修饰
static Object obj=new Object();//定义一个类似于x似的静态变量,用于代码监视器
public static void main(String[] args) {
new Thread(){//在主函数中定义两个内部类,实现两个窗口的模拟
@Override
public void run() {//重写run()方法
while(true){
synchronized (obj) {//用synchronized的方式来实现代码的同步
if (x > 1) {
System.out.println(Thread.currentThread().getName() + "还剩票数:" + x--);//输出所剩的票数
} else {
break;
}
}
}
}
}.start();//调用start()方法开启线程
new Thread(){
@Override
public void run() {
while(true){
synchronized (obj) {//用synchronized的方式来实现代码的同步
if (x > 0) {
System.out.println(Thread.currentThread().getName() + "还剩票数:" + x--);
} else {
break;
}
}
}
}
}.start();
}
}
来举个小例子
package com.ligang.com;
import java.text.BreakIterator;
/*
* 银行有一个账户。
* 有两个储户分别向同一个账户存3000元,每次存1000,存3次。每次存完打印账户余额。
*加上线程的通信,实现两用户交替向银行卡里存钱
*wait();暂停进程使用
*notify()/notafyAll()唤醒进程
*
*/
public class Desposit implements Runnable {
double x = 0;
@Override
public void run() {
for (int i = 0; i < 3; i++) {
synchronized (this) {
notify();// 唤醒进程
x = x + 1000;
System.out.println("当前用户:" + Thread.currentThread().getName() + "余额为:" + x);
try {
wait();// 等待一下 释放cpu资源
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
public static void main(String[] args) {
Desposit p = new Desposit();
Thread p1 = new Thread(p);
Thread p2 = new Thread(p);
p1.setName("客户1");
p2.setName("客户2");
p1.start();
p2.start();
}
}
生产者与消费者的经典例题
package com.ligang.com;
import javax.print.attribute.standard.NumberOfInterveningJobs;
import javax.sound.midi.VoiceStatus;
/*
* 生产者与消费者的经典例题
*/
class Clerk {
int product;
public synchronized void addProduct() {// 生产
if (product > 10) {
try {
wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
} else {
product++;
System.out.println(Thread.currentThread().getName()+"生产的第"+product+"个产品");
notify();
}
}
public synchronized void subProduct() {// 消费
if (product <0) {
try {
wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
} else {
System.out.println(Thread.currentThread().getName()+"消费的第"+product+"个产品");
product--;
notify();
}
}
}
class Produce implements Runnable {// 生产者生产
Clerk clerk;
public Produce(Clerk clerk) {
this.clerk = clerk;
}
@Override
public void run() {
System.out.println("生产者生产产品");
while (true) {
try {
Thread.currentThread();
Thread.sleep(100);
} catch (InterruptedException e) {
e.printStackTrace();
}
clerk.addProduct();
}
}
}
class Couser implements Runnable {// 消费者消费
Clerk clerk;
public Couser(Clerk clerk) {
this.clerk = clerk;
}
@Override
public void run() {
System.out.println("消费者消费产品");
while (true) {
try {
Thread.currentThread();
Thread.sleep(100);
} catch (InterruptedException e) {
e.printStackTrace();
}
clerk.subProduct();
}
}
}
public class ProductTest {
public static void main(String[] args) {
Clerk s=new Clerk();
Produce p1=new Produce(s);
Couser s1=new Couser(s);
Thread t1=new Thread(p1);
Thread t3=new Thread(p1);
Thread t4=new Thread(p1);
Thread t2=new Thread(s1);
t1.setName("生产者1:");
t3.setName("生产者2:");
t4.setName("生产者3:");
t2.setName("消费者:");
t1.start();
t2.start();
t3。start();
t4.start();
}
}
这篇博客中写的文字很少,我想记得都写在了代码的注释中了,总结起来还是很简单的 线程的创建我写了两种方式,同步我也写了两个方式,后面写了两个作业题,把前面学的知识总结了一下,,菜鸟敬上,大神们,海涵