java中的多线程——进度1
import java.util.*;
public static void main(String[] args) {
/*
final可以修饰类,方法,变量。
final修饰的类不可以被继承。
final修饰的方法不可以被覆盖。
final修饰的变量是一个常量。只能被赋值一次。
内部类只能访问被final修饰的局部变量。
*/
/*抽象类和抽象方法
*/
/*
接口
*/
/*try catch
在try块,catch块,finally块和异常块外存在return语句的情况。finally中的return是会提前退出的,
finally中的代码在其他两块中中存在return是要运行的,只不过不会改变return中结果。
*/
/**
线程定义的两种方法,
第一是继承Thread类并覆盖run方法,start()方法调用run()方法开启线程和任务。run()方法只是主函数中的一个普通方法不会开启多线程。由于java不支持多继承,当需要多线程的子类有父类时,可以通过接口的方式实现多继承。所以出现第二种方法。
第二是实现runable接口,并实现接口中的run方法,把线程任务封装在run方法中,通过Thread类创建线程对象。
线程中的方法
调用当前线程:Thread.currentThread().getName();
start(),stop(),sleep(time),wait(),notify()
构造方法:Thread();Thread(Runnable r)通过Thread的这个构造方法传递定义好的Runnable子类接口实现第二种方法的多线程创建;
线程的状态
cpu的执行资格:可以被cpu的处理,在处理队列中排队
cpu的执行权:正在被cpu的处理
①被创建,
②运行:具备执行资格和执行权,
③冻结:释放执行权和执行资格,
④消亡:
⑤临时阻塞:具备执行资格还不具备执行权
线程中的问题
各线程之间互相不会干扰
class Thread
{
private Runnable r;
Thread()
{
}
Thread(Runnable r)
{
this.r = r;
}
public void run()
{
if(r!=null)
r.run();
}
public void start()
{
run();//如果实现子线程类调用的是子线程中实现的run方法,子线程中的run()覆盖了父类Thread中的方法。
}
}
//第一种创建多线程的方法
class SubThread extends Thread
{
public void run()
{
System.out.println("haha");
}
}
//第二种创建多线程的方法
//单独将任务封装起来,按照面向对象的思想将任务封装成对象,避免了java单继承的局限性
class ThreadImpl implements Runnable
{
public void run()
{
system.out.println("runnable run");
}
}
ThreadImpl i = new ThreadImpl();
Thread t = new Thread(i);
t.start();
//多线程卖票
public class Ticket extends Thread{
private int num = 100;
//private static int num = 100;//静态变量实现唯一
public void run(){
while(true){
if(num>0){
system.out.println(Thread.currentThread().getName()+"...."+num--);
}
}
}
}
class ticketDemo{
public static void main(String[] args){
Ticket t1 = new Ticket();
Ticket t2 = new Ticket();
Ticket t3 = new Ticket();
Ticket t4 = new Ticket();
//Ticket t2 = new Ticket();
//Ticket t3 = new Ticket();
//Ticket t4 = new Ticket();
t1.start();
t2.start();
t3.start();
t4.start();
//t1.start();t1.start();t1.start();t1.start();
}
}
//多线程卖票,实现Runnable接口实现
public class Ticket implements Runnable{
private int num = 100;
//private static int num = 100;//静态变量实现唯一
public void run(){
while(true){
if(num>0){
system.out.println(Thread.currentThread().getName()+"...."+num--);
}
}
}
}
class ticketDemo{
public static void main(String[] args){
Ticket t = new Ticket();//创建一个线程任务对象
Thread t1 = new Thread(t);
Thread t2 = new Thread(t);
Thread t3 = new Thread(t);
Thread t4 = new Thread(t);
t1.start();
t2.start();
t3.start();
t4.start();
//t1.start();t1.start();t1.start();t1.start();
}
}
线程中的安全问题:
当一个线程在执行操作共享数据的多条代码过程中,其他线程参与了运算,就会导致线程安全问题的产生。
当编号num为1的线程切换为冻结状态,有执行资格但没有执行权的时候。下一个线程可以运行,当切换的线程切换过来后,会出现0号票的情况,线程安全出现问题。
原因:多个线程操作共享的数据;操作共享数据的线程代码有多条;
public void run(){
private int num = 100;
public void run(){
while(true){
if(num>0)
{
try{Thread.sleep(10);}catch(InterruptedException e){}
System.out.println(Thread.currentThread().getName()+num--);
}
}
}
}
线程安全问题的解决,线程代码块的同步(火车上的卫生间),由于同步外的线程都要判断同步锁,所以相应的降低了效率。
同步去前提:同步中必须有多个线程并使用同一个锁
public void run(){
private int num = 100;
object obj = new object();
public void run(){
while(true){
synchronize(obj)
{
if(num>0)
{
try{Thread.sleep(10);}catch(InterruptedException e){}
System.out.println(Thread.currentThread().getName()+num--);
}
}
}
}
}
//银行储户的例子
class Bank
{
private int sum;
private Object obj = new Object();
public void add(int num)
{
synchronized(obj)//同步代码块在调用的地方。
{
sum = sum + num;
try{Thread.sleep(10);}catch(InterruptedException e){}
System.out.println("sum="+sum);
}
}
}
class Cus implements Runnable
{
private Bank b = new Bank();
public void run()
{
for(int x=0; x<3;x++)
{
b.add(100);
}
}
}
//银行储户的例子(同步关键字作为函数的修饰符)(同步代码块到同步函数的转换)
//同步函数使用的锁是this,所以在同步代码块和同步函数混合使用的时候在同步代码块加的锁为this。
//同步函数和同步代码块的区别
1,同步函数的锁是固定的this
2,同步代码块是任意的对象
3,同步代码块的使用较多。
//静态同步函数的锁
1,在同步代码块加锁的时候与同步函数的区别
synchronize(this)
{
if(num>0)
{
try{Thread.sleep(10);}catch(InterruptException e){}
System.out.println(Thread.currenThread.getName()+num--);
}
}
2,在同步代码块加锁的时候与同步函数的区别
静态的同步函数使用的锁是 该函数所属字节码文件对象,
可以用getClass方法获取,也可以用当前类名.class表示
synchronize(this.getClass())//this是当前票对象
{
if(num>0)
{
try{Thread.sleep(10);}catch(InterruptException e){}
System.out.println(Thread.currenThread.getName()+num--);
}
}
class Bank
{
private int sum;
private Object obj = new Object();
public synchronized void add(int num)//同步函数
{
// synchronized(obj)//同步代码块在调用的地方。
// {
sum = sum + num;
try{Thread.sleep(10);}catch(InterruptedException e){}
System.out.println("sum="+sum);
// }
}
}
class Cus implements Runnable
{
private Bank b = new Bank();
public void run()
{
for(int x=0; x<3;x++)
{
b.add(100);
}
}
}
//多线程下的单例设计模式
//饿汉式的
class Single
{
private static final Single s = new Single();
private Single(){}
public static Single getInstance()
{
return s;
}
}
//懒汉式
calss Single
{
private static Single s = null;
private Single(){}
public static synchronized Single getInstance()
{
if(s==null){//解决效率问题
synchronized(Single.class){//此处不能用this.getClass()因为getclass方法是非静态的。
if(s==null)
s = new Single();
}
}
}
}
class SingleDemo
{
public static void main(String[] args)
{
System.out.println("hello world!");
}
}
死锁:代码块中的锁有同步函数的锁,同步函数的锁中有代码块的锁,两个线程每个拿到一半资源,互不相让。
死锁实例
class Test implements Runnable
{
private boolean flag;
Test(boolean flag)
{
this.flag = flag;
}
public void run()
{
if(flag)
{
while(true)
{
synchronized(MyLock.locka)
{
System.out.println(thread.current.getName()+"if locaka..");
synchronized(MyLock.lockb)
System.out.println(thread.current.getName()+"if locakb..");
}
}
}
else
{
while(true)
{
synchronized(MyLock.lockb)
{
System.out.prinln(thread.current.getName()+"else lockb...");
synchronized(MyLock.locka)
{
System.out.println(thread.current.getName()+"else locka...");
}
}
}
}
}
}
class MyLock
{
pbulic static final Object locka = new Object();
public static final Object lockb = new Object();
}
*/
/**
线程通信
多个线程在处理统一资源,但是任务不同
等待唤醒机制 ,wait(),notify(),notifyall()
//资源
class Resource
{
String name;
String sex;
boolean flag = false;
}
//输入
class Input implements Runnable
{
Resource r;
input(Resource r)
{
this.r = r;
}
public void run()
{
int x = 0;
while(true)
{
synchronized(r)
{
if(r.flag)
r.wait();
if(x==0)
{
r.name="mike";
r.sex="nan";
}
else
{
r.name="丽丽";
r.sex="女女女女女";
}
r.flag = true;
r.notify();
}
x = (x+1)%2;
}
}
}
//输出
class Output implements runnable
{
Resource r;
Output(Resource r)
{
this.r = r;
}
public void run()
{
while(true)
{
synchronized(r)
{
if(!flag)
r.wait();
System.out.println(r.name+"..."+r.sex);
r.flag = false;
r.notify();
}
}
}
}
class RsourceDemo2
{
public static void main(String[] args)
{
//创建资源
Resource r = new Resource();
//创建任务
Input in = new Input(r);
Output out = new Output(r);
//定义线程
Thread t1 = new Thread(in);
Thread t2 = new Thread(out);
//开启线程
t1.start();
t2.start();
}
}
/*
等待唤醒机制,生产者消费者模式
class Resouce
{
private String name;
private int count=1;
private boolean flag = false;
public void set(String name)
{
if(flag)
try{this.wait();}catch(InterruptedException e){}
this.name = name+count;
count++;
System.out.println(Thread.currentThread().getName()+"...生产者。。。。"+this.name);
flag = true;
notify();
}
public void out()
{
if(flag)
try{this.wait();}catch(InterruptedException e){}
System.out.println(Thread.currentThread().getName()+"...消费者。。。。。"+this.name);
flag = false;
notify();
}
}
class producer implements Runnable
{
private Resource r;
Producer(Resource r)
{
this.r = r;
}
pbulic void run()
{
while(true)
{
r.out();
}
}
}
class consumer implements Runnable
{
private Resource r;
Producer(Resource r)
{
this.r = r;
}
pbulic void run()
{
while(true)
{
r.set("烤鸭");
}
}
}
class ProducerConsumerDemo
{
public static void main(String[] args)
{
//创建资源
Resouce r = new Resource();
//创建任务
Producer pro = new Producer();
Consumer con = new Consumer();
//创建线程
Thread t1 = new Thread(pro);
Thread t2 = new Thread(con);
//开启线程
t1.start();
t2.start();
}
}
//多生产和多消费的问题
class Resouce
{
private String name;
private int count=1;
private boolean flag = false;
public void set(String name)
{
while(flag)//多次判断,让阻塞的线程继续判断标记,解决了线程获取执行权后是否要运行。
try{this.wait();}catch(InterruptedException e){}
this.name = name+count;
count++;
System.out.println(Thread.currentThread().getName()+"...生产者。。。。"+this.name);
flag = true;
notifyAll();//唤醒所有,解决了死锁问题。
}
public void out()
{
while(flag)
try{this.wait();}catch(InterruptedException e){}
System.out.println(Thread.currentThread().getName()+"...消费者。。。。。"+this.name);
flag = false;
notifyAll();
}
}
class producer implements Runnable
{
private Resource r;
Producer(Resource r)
{
this.r = r;
}
pbulic void run()
{
while(true)
{
r.out();
}
}
}
class consumer implements Runnable
{
private Resource r;
Producer(Resource r)
{
this.r = r;
}
pbulic void run()
{
while(true)
{
r.set("烤鸭");
}
}
}
class ProducerConsumerDemo
{
public static void main(String[] args)
{
//创建资源
Resouce r = new Resource();
//创建任务
Producer pro = new Producer();
Consumer con = new Consumer();
//创建线程
Thread t1 = new Thread(pro);
Thread t2 = new Thread(con);
//开启线程
t1.start();
t2.start();
}
}
*/
//多生产和多消费的问题,由于为了防止多消费者和多生产者多线程中的思索问题,
//在消费者和生产者完成相应操作后必须把线程池中阻塞的线程进行全部唤醒,这样会导致
//一个问题就是,每次唤醒的线程中会有本方的线程,虽然通过while判断进行再次wait阻塞并放入线程中
//但是这样会浪费系统的开销。所以必须实现在同一个锁中的多个任务多线程操作,这样就引出了同一个锁中的多个监视器的感念。
//由于生产者和消费者所处的监视器可以分开,所以在唤醒操作中,可以实现只唤醒对方的线程任务。
//这个实现方法通过java1.5中的新特性,LOCK接口实现 ,通过实例化lock接口的子类来定义多个监视器。
//condition接口:出现替代了object中的wait,notify notifyAll方法
// 将这些监视器方法单独进行封装,变成Condition监视器对象。
// 可以任意锁进行组合。
// await(); wait();
// signal(); notify();
// signalAll(); notifyAll();
/*
class Resouce
{
private String name;
private int count=1;
private boolean flag = false;
//创建一个锁对象
Lock lock = new ReentrantLock();
//通过已有锁获取该锁上的两组监视器对象
Condition producer_con = lock.newcondition();
condition consumer_con = lock.newCondition();
public void set(String name)
{
while(flag)//多次判断,让阻塞的线程继续判断标记,解决了线程获取执行权后是否要运行。
try{producer_con.await();}catch(InterruptedException e){}
this.name = name+count;
count++;
System.out.println(Thread.currentThread().getName()+"...生产者。。。。"+this.name);
flag = true;
consumer_con.singleAll();//唤醒所有,解决了死锁问题。
}
public void out()
{
while(flag)
try{consumer_con.await();}catch(InterruptedException e){}
System.out.println(Thread.currentThread().getName()+"...消费者。。。。。"+this.name);
flag = false;
consumer_con.singleAll();
}
}
class producer implements Runnable
{
private Resource r;
Producer(Resource r)
{
this.r = r;
}
pbulic void run()
{
while(true)
{
r.out();
}
}
}
class consumer implements Runnable
{
private Resource r;
Producer(Resource r)
{
this.r = r;
}
pbulic void run()
{
while(true)
{
r.set("烤鸭");
}
}
}
class ProducerConsumerDemo
{
public static void main(String[] args)
{
//创建资源
Resouce r = new Resource();
//创建任务
Producer pro = new Producer();
Consumer con = new Consumer();
//创建线程
Thread t1 = new Thread(pro);
Thread t2 = new Thread(con);
//开启线程
t1.start();
t2.start();
}
}
*/
}
java中的多线程——进度1的更多相关文章
- java中的多线程——进度2
package src;/*多线程总结:1,进程和线程的概念. |--进程: |--线程:2,jvm中的多线程体现. |--主线程,垃圾回收线程,自定义线程.以及他们运行的代码的位置 ...
- Android学习记录(5)—在java中学习多线程下载之断点续传②
在上一节中我们学习了在java中学习多线程下载的基本原理和基本用法,我们并没有讲多线程的断点续传,那么这一节我们就接着上一节来讲断点续传,断点续传的重要性不言而喻,可以不用重复下载,也可以节省时间,实 ...
- Java 中传统多线程
目录 Java 中传统多线程 线程初识 线程的概念 实现线程 线程的生命周期 常用API 线程同步 多线程共享数据的问题 线程同步及实现机制 线程间通讯 线程间通讯模型 线程中通讯的实现 @(目录) ...
- Java中使用多线程、curl及代理IP模拟post提交和get访问
Java中使用多线程.curl及代理IP模拟post提交和get访问 菜鸟,多线程好玩就写着玩,大神可以路过指教,小弟在这受教,谢谢! 更多分享请关注微信公众号:lvxing1788 ~~~~~~ 分 ...
- 【转】Java中的多线程学习大总结
多线程作为Java中很重要的一个知识点,在此还是有必要总结一下的. 一.线程的生命周期及五种基本状态 关于Java中线程的生命周期,首先看一下下面这张较为经典的图: 上图中基本上囊括了Java中多线程 ...
- Java中的 多线程编程
Java 中的多线程编程 一.多线程的优缺点 多线程的优点: 1)资源利用率更好2)程序设计在某些情况下更简单3)程序响应更快 多线程的代价: 1)设计更复杂虽然有一些多线程应用程序比单线程的应用程序 ...
- java中的多线程 // 基础
java 中的多线程 简介 进程 : 指正在运行的程序,并具有一定的独立能力,即 当硬盘中的程序进入到内存中运行时,就变成了一个进程 线程 : 是进程中的一个执行单元,负责当前程序的执行.线程就是CP ...
- Java中的多线程=你只要看这一篇就够了
如果对什么是线程.什么是进程仍存有疑惑,请先Google之,因为这两个概念不在本文的范围之内. 用多线程只有一个目的,那就是更好的利用cpu的资源,因为所有的多线程代码都可以用单线程来实现.说这个话其 ...
- Java中使用多线程、curl及代理IP模拟post提交和get訪问
Java中使用多线程.curl及代理IP模拟post提交和get訪问 菜鸟,多线程好玩就写着玩.大神能够路过不吝赐教.小弟在这受教.谢谢! 很多其它分享请关注微信公众号:lvxing1788 ~~~~ ...
随机推荐
- Delphi- 连接MySQL数据库BDE
Delphi使用ADO可以连接MSSQL和ACCESS,但似乎不能连接MYSQL和ORACEL,如果要连接MYSQL和ORACLE得使用BDE. 一.连接方法 首先得先安装mysql驱动程序_mysq ...
- CopyU!SW新版发布!
CopyU!SW新版发布,版本号为:2.1.412.213 主要更新内容如下: 此版本(2.1.412.213)主要作了如下更新: 1.修复了CopyU!SW版本中的运行模式规则的设定错 ...
- Unsupervised Feature Learning and Deep Learning(UFLDL) Exercise 总结
7.27 暑假开始后,稍有时间,“搞完”金融项目,便开始跑跑 Deep Learning的程序 Hinton 在Nature上文章的代码 跑了3天 也没跑完 后来Debug 把batch 从200改到 ...
- 菜鸟学习-C语言函数参数传递详解-结构体与数组 分类: C/C++ Nginx 2015-07-14 10:24 89人阅读 评论(0) 收藏
C语言中结构体作为函数参数,有两种方式:传值和传址. 1.传值时结构体参数会被拷贝一份,在函数体内修改结构体参数成员的值实际上是修改调用参数的一个临时拷贝的成员的值,这不会影响到调用参数.在这种情况下 ...
- linux 打补丁
http://blog.csdn.net/maotianwang/article/details/11107083
- 读写应用程序数据-CoreData
coreData数据最终的存储类型可以是:SQLite数据库.XML.二进制.内存里.自定义的数据类型. 和SQLite区别:只能取出整个实体记录,然后分解,之后才能得到实体的某个属性. 1.创建工程 ...
- GitHub干货分享(APP引导页的高度集成 - DHGuidePageHUD)
每一个APP都会用到APP引导页,分量不重但是不可缺少,不论是APP的首次安装还是版本的更新,首先展现给用户眼前的也就只有它了,当然这里讲的不是APP引导页的美化而是APP引导页的高度集成,一行代码搞 ...
- 网格GridLayout建立
import java.awt.*;public class GridFlowout extends Frame { public GridFlowout (String str){ {setTitl ...
- linux如何查进程、杀进程
本文系转载,转载原文地址:http://blog.sina.com.cn/s/blog_637112040100vl53.html 1.查进程 ps命令查找与进程相关的PID号: ps a 显 ...
- java查询手机号码归属地
package com; import java.io.BufferedReader; import java.io.IOException; import java.io.InputStreamRe ...