📄 thread.txt
字号:
public Product(int productID,String productName)
{
this.productID=productID;
this.productName=productName;
}
public String toString()
{
StringBuffer sb=new StringBuffer();
sb.append("{");
sb.appentd("productID="+this.productID+";");
sp.append("productName="+this.productName+";");
sb.append("}");
return sb.toString();
}
}
public class WareHouse
{
private int maxSize;
private int size;
private int front=0;
private int vear=-1;
private Product products[];
public WareHouse(int maxSize)
{
this.maxSize=maxSize;
this.size=0;
products=new Product[this.maxSize];
}
public synchronized void add(Product product)
{
//只有Producer才可以生产产品
Thread temp=Thread.currendThead();
if(temp.getClass.equals(Producer.class))
{
Producer producer=(Producer)temp;
while(this.isFull() && producer.isRunning)
{
System.out.println(producer.getName()+"要等待");
wait;
System.out.println(producer.getName()+"激活了");
}
this.products[++vear]=product;
if(vear==this.maxSize-1)
{
vear=-1;
}
}
}
public synchronized Product remove()
{
if(this.isEmpty())
{
wait;
}
Product temp=this.products[front++];
if(front==this.maxSize)
{
front=0;
}
return temp;
}
public boolean isFull()
{
retrurn this.siz==maxSize;
}
public boolean isEmpty()
{
return this.size==0;
}
}
public class Producer extends Thread
{
private WareHouse wareHouse;
private boolean isRunning=true;
private static int i;
public Producer(String threadName,WareHouse wareHouse)
{
super(threadName);
this.wareHouse=wareHouse;
}
public void run()
{
while(isRunning)
{
i++;
Product product=new Product(i,"name"+i);
wareHouse.add(product);
Thread.sleep(1000);
}
}
public void stopProducer()
{
synchronized(wareHouse)
{
this.isRunning=false;
//在关闭前激活一下所有的线程
notifyAll();
}
}
}
public class Consumer extends Thread
{
public void run()
{
}
}
三、join:让主线程等待所有的子线程执行完后再执行。
四、setDaemon:在线程start之前设置,将当前线程设置为守护线程,
当其它线程结束后,守护线程自动停止。
守护线程为其它线程提供服务。
五、setPriority:设置线程运行的优先级,默认是5,优先级越高越提前
执行。
六、取出虚拟机下的所有线程
线程组:ThreadGroup,一个线程组可以有多个线程,也可以有很多子线程组
线程:Thread
实例化线程:
new Thread(Runnable run);
new Thread(Runnable run,String ThreadName);
new Thread(String ThreadName);
//基于runnable实现一个线程,ThreadName是线程的名称,ThreadGroup代表当前线程属于那一个线程组
new Thread(ThreadGroup tg,Runnable run,String ThreadName);
new Thread(ThreadGroup tg,String ThreadName)
实例化线程组:
//当前的线程组从属于那一个线程组
new ThreadGroup(ThreadGroup tg,String ThreadName);
new ThreadGroup(String ThreadName)
方法:
currentThread():得到调用当对象的线程
enumerate(Thread[] tarray): 将当前线程的线程组及其子组中的每一个活动线程引用复制到指定的数组中。
enumerate(Thread[] tarray,false): 当前线程组内的每一个活动线程引用复制到数组中。
enumerate(ThreadGroup[] tarray): 将当前线程的线程组及其子组中的每一个活动线程引用复制到指定的数组中。
enumerate(ThreadGroup[] tarray,false): 当前线程组内的每一个活动线程组的引用复制到数组中。
getThreadGroup();返回该线程所属的线程组。
void interrupt(): 中断线程。
static boolean interrupted(): 测试当前线程是否已经中断。
boolean isAlive(): 测试线程是否处于活动状态。
boolean isDaemon():测试该线程是否为守护线程。
boolean isInterrupted():测试线程是否已经中断。
void join():等待该线程终止。
setPriority(int newPriority) :线程的优先级。
yield():暂停当前正在执行的线程对象,释放资源,并执行其他线程,将其放到线程队列的最后。
activeCount() :返回当前线程的线程组中活动线程的数目。
七、产生一个线程是很浪费时间的,如果事选将多个线程放到线程池中,
有任务时取出一个线程,没有任务时线程处于等待状态。
线程池:
1、有线程数组,存放活动线程
2、有一个任务列表,存放任务,将任务依次取出
一、死锁:一个线程占用一个资源,又想得到另一个线程占用的资源,只能等待。
另一个线程占用一个资源,又想得到前一个线程占用的资源,也只能等待。
这样两个线程出现死锁。
public class MyThread1 extends Thread
{
private Object resource1;
private Object resource2;
public MyThread1(Object resource1,Object resource2)
{
this.resource1=resource1;
this.resource2=resource2;
}
public void run()
{
synchronized(resource1)
{
System.out.println("正在执行资源1号");
Thread.sleep(50);
synchronized(resource2)
{
System.out.println("正在执行资源2号");
}
}
}
}
public class MyThread2 extends Thread
{
private Object resource1;
private Object resource2;
public MyThread2(Object resource1,Object resource2)
{
this.resource1=resource1;
this.resource2=resource2;
}
public void run()
{
synchronized(resource2)
{
System.out.println("正在执行资源2号");
Thread.sleep(50);
synchronized(resource1)
{
System.out.println("正在执行资源1号");
}
}
}
}
二、Timer过一段时间执行一个线程或某一时间点执行一个线程
或隔多长时间执行一个线程。
1、实现执行任务的线程,必须继承于TimerTask
public class MyThread extends TimerTask
{
public void run()
{
}
}
2、通过Timer类调用
Timer timer=new Timer();
MyThread mt=new MyThread();
timer.schedule(mt,1000);//1秒后运行线程mt
timer.schedule(mt,1000,1000);//1秒后运行线程mt,同时每隔1秒后执行mt
timer.schedule(mt,date);//某个时间点执行mt
timer.cancel();//代表退出
四、线程的作用
进程内的并发
五、线程与进程的区别
共同点:
都是并发
不同点:
进程有独立的内存空间,线程没有独立内存空间。
进程间的通信耗费较大的资源,线程间的通信比较容易。
进程的并发是由线程实现的。
六、线程实现
1、继承于Thread类,覆盖run()方法,通过start启动线程,调用run方法。
2、实现Runnable接口,实现run()方法。实例化该类,通过构造子将其传到一个Thread对象中
,通过start启动线程,调用run方法
七、线程的同步
--脏读:后一个事务用了前一个事务没有确认的数据
事务1
update buy set amount=amount+100 where buyID=1;
rollback;
事务2:在事务1修改但没有执行rollback前,执行当前update交提交
update buy set amount=amount+100 where buyID=1;
commit;
--覆盖更新:后一个事务将前一个事务的更新覆盖了。
(update一读到就加锁)两个事务同时读取,因为事务1所在主机速度快先更新并提交,
然后事务2更新并提交。
事务1
update buy set amount=amount+100 where buyID=1;
commit;
事务2:
update buy set amount=amount+100 where buyID=1;
commit;
脏读就是指当一个事务正在访问数据,并且对数据进行了修改,而这种修改还没有提交到数据库中,这时,另外一个事务也访问这个数据,然后使用了这个数据。因为这个数据是还没有提交的数据,那么另外一个事务读到的这个数据是脏数据,依据脏数据所做的操作可能是不正确的。不可重复读是指在一个事务内,多次读同一数据。在这个事务还没有结束时,另外一个事务也访问该同一数据。那么,在第一个事务中的两次读数据之间,由于第二个事务的修改,那么第一个事务两次读到的的数据可能是不一样的。这样就发生了在一个事务内两次读到的数据是不一样的,因此称为是不可重复读。幻觉读是指当事务不是独立执行时发生的一种现象,例如第一个事务对一个表中的数据进行了修改,这种修改涉及到表中的全部数据行。同时,第二个事务也修改这个表中的数据,这种修改是向表中插入一行新数据。那么,以后就会发生操作第一个事务的用户发现表中还有没有修改的数据行,就好象发生了幻觉一样。
什么是线程同步:一个对象的一个同步方法被一个线程调用,另一个线程不管调用当前同步方法
还是其它的同步方法只能等待同步方法执行结束,调用非同步方法不影响。
实现方法:
public synchronized void a1()
{
}
在线程的run方法中说明是一个同步对象,调用这个对象的所有方法都是同步方法。
synchronized(co)
{
co.test1();
}
通讯的两种方式:
1、基于tcp/ip协议,用Sockect实现
特点:产生会话,稳定,每一次交互都有确认。
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -