好吧,这是一个双重目的的问题。我希望从中获得的主要好处是对多线程的更多了解。关于多线程,我是一个完全的新手,这是我第一次尝试在多线程中执行任何操作。我希望带走的另一件事是一些家庭作业方面的帮助,我正在将其转变为一个更加复杂的弗兰肯项目,以进行娱乐和学习。在这个问题的第一部分中,我将详细说明我在作业中一直在研究的线程的思路和方法。如果我做不好的事情,需要修复,无论如何,请告诉我,以便我学习。同样,我对多线程几乎一无所知。
首先,我目前正在上一门计算机科学类(class),更好的是,它有家庭作业,使用的是我已经学过的技术和数据结构,因此并不具有挑战性。为了不让我完全厌倦,我尝试着做一个简单的项目(创建一个链表和一个排序的链表),然后将其变成一个多线程的弗兰肯程序。我希望将新元素添加到单独的线程中并从队列中获取输入的方法(对于无序列表不是完全必要的,但是对于正确的排序将更加有用),对于有序列表,我想要一个一个单独的线程将在列表中巡逻,以确保所有元素都井井有条(我不允许更改的方法之一将返回对具有完全公共(public)数据的整个节点的引用)。这些是我要创建的两个主要内容,但绝对不是我可能想要尝试找出的唯一内容。这意味着几乎只是一个学习多线程的测试,因此我并不是为了实用性而专门设计该项目。如果您想对什么是应采用线程还是不采用什么线程的良好编程习惯发表评论,将不胜感激。
我最近采取的一个步骤是,通过阅读有关StackOverflow本身的一篇文章而得出的想法是,我创建了一个主类,该主类已将Threads传递给它,这样它就可以停止它们并在程序结束时清除所有内容。这是通过使用someThread.interrupt()并让Thread的run()方法检查该异常来完成的。但是,我发现此方法存在问题:大多数情况下,贯线程程并调用interrupt()的循环实际上并未运行。这是该方法的代码:
public static void stopAllThreads()
{
boolean stopped = false;
while( !stopped )
{
System.out.println( "Stopping all threads" );
synchronized( threads )
{
System.out.println( "Threads being stopped: " + threads.size() );
for( int i = 0; i < threads.size(); i++ )
{
System.out.println( "Stopping: " + threads.get( i ) );
threads.get( i ).interrupt();
}
threads.clear();
stopped = true;
}
}
}
public static void main( String[] args )
{
// always make sure this is the first thing created
ActiveThreads bla = new ActiveThreads();
Comparator< Integer > temp = new Comparator< Integer >()
{
public int compare( Integer i, Integer j )
{
if( i > j ) return 1;
if( i < j ) return -1;
return 0;
}
};
List< Integer > woogle = new List< Integer >( temp );
woogle.add( 1 );
woogle.add( 2 );
woogle.add( 3 );
woogle.add( 4 );
System.out.println( woogle );
ActiveThreads.stopAllThreads();
}
private class AddThread implements Runnable
{
public AddThread()
{
}
public void run()
{
while( running )
{
synchronized( addQueue )
{
while( !addQueue.isEmpty() )
{
System.out.println( "Going through queue" );
T temp = addQueue.poll();
if( head == null )
{
head = new Node< T >();
last = head;
head.data = temp;
largest = temp;
smallest = temp;
}
else
{
last.next = new Node< T >();
last.next.data = temp;
last = last.next;
if( mComparator.compare( temp, largest ) == 1 )
{
largest = temp;
}
else if( mComparator.compare( temp, smallest ) == -1 )
{
smallest = temp;
}
}
++size;
}
}
System.out.println( "Pausing " + addThread );
synchronized( addThread )
{
pause( 200 );
}
}
}
private void pause( long time )
{
try
{
addThread.wait( time );
}
catch ( InterruptedException e )
{
running = false;
addThread.notify();
}
}
private boolean running = true;
}
addThread = new Thread( new AddThread(), "Thread for adding elements" );
addThread.setPriority( 6 );
addThread.start();
ActiveThreads.addThread( addThread );
public class List< T > implements Iterable< T >, Comparable< List< T > >
{
// you may not change this inner class!
class Node< D >
{
D data;
Node< D > next;
}
public List( Comparator< T > comparator )
{
mComparator = comparator;
head = null;
last = null;
size = 0;
addQueue = new LinkedList< T >();
addThread = new Thread( new AddThread(), "Thread for adding elements" );
addThread.setPriority( 6 );
addThread.start();
ActiveThreads.addThread( addThread );
}
public void add( T newElt )
{
synchronized( addQueue )
{
addQueue.add( newElt );
}
}
public T get( int index )
{
if( index > size )
throw new IndexOutOfBoundsException();
Node< T > temp = head;
for( int i = 0; i < index; i++ )
{
temp = temp.next;
}
return temp.data;
}
public Node< T > lookup( T element )
{
Node< T > temp = head;
for( int i = 0; i < size; i++ )
{
if( temp.data == element )
return temp;
temp = temp.next;
}
throw new NoSuchElementException();
}
public int size()
{
return size;
}
public boolean isEmpty()
{
return head == null;
}
public void delete( T element )
{
throw new UnsupportedOperationException("You must implement this method.");
}
public void replace( T oldElt, T newElt )
{
try
{
Node< T > temp = lookup( oldElt );
temp.data = newElt;
}
catch( NoSuchElementException e )
{
throw e;
}
}
public T getLargest()
{
return largest;
}
public T getSmallest()
{
return smallest;
}
public List< T > copy()
{
throw new UnsupportedOperationException("You must implement this method.");
}
public String toString()
{
StringBuffer ret = new StringBuffer();
int i = 0;
for( T x : this )
{
System.out.println( "Loop: " + i++ );
ret.append( x + " " );
}
return ret.toString();
}
public int compareTo( List< T > other )
{
throw new UnsupportedOperationException("You must implement this method.");
}
public ListIterator< T > iterator()
{
return new ListIterator< T >( head );
}
private class ListIterator< E > implements Iterator< E >
{
private ListIterator( Node< E > head )
{
cur = head;
}
public boolean hasNext()
{
if( cur == null )
return false;
System.out.println( "Iterator: " + cur.data );
return cur.next == null;
}
@SuppressWarnings("unchecked")
public E next()
{
Node< E > temp = cur;
cur = cur.next;
return (E)temp.data;
}
public void remove()
{
throw new UnsupportedOperationException("You do NOT need to implement " +
"this method.");
}
private Node< E > cur;
}
private class AddThread implements Runnable
{
public AddThread()
{
}
public void run()
{
while( running )
{
synchronized( addQueue )
{
while( !addQueue.isEmpty() )
{
System.out.println( "Going through queue" );
T temp = addQueue.poll();
if( head == null )
{
head = new Node< T >();
last = head;
head.data = temp;
largest = temp;
smallest = temp;
}
else
{
last.next = new Node< T >();
last.next.data = temp;
last = last.next;
if( mComparator.compare( temp, largest ) == 1 )
{
largest = temp;
}
else if( mComparator.compare( temp, smallest ) == -1 )
{
smallest = temp;
}
}
++size;
}
}
System.out.println( "Pausing " + addThread );
synchronized( addThread )
{
pause( 200 );
}
}
}
private void pause( long time )
{
try
{
addThread.wait( time );
}
catch ( InterruptedException e )
{
running = false;
addThread.notify();
}
}
private volatile boolean running = true;
}
private Comparator< T > mComparator;
private Node< T > head, last;
private Thread addThread;
// replace this with your own created class later
private Queue< T > addQueue;
private int size;
private T largest, smallest;
}
public class ActiveThreads
{
public ActiveThreads()
{
if( threads == null )
{
threads = new ArrayList< Thread >();
}
if( threadsMonitor == null )
{
ThreadsMonitor monitor = new ThreadsMonitor();
Thread thread = new Thread( monitor, "Active Threads Monitor" );
thread.setPriority( 3 );
thread.start();
threadsMonitor = thread;
}
}
public static void stopMonitoring()
{
synchronized( threadsMonitor )
{
threadsMonitor.interrupt();
}
}
public static void addThread( Thread t )
{
synchronized( threads )
{
threads.add( t );
System.out.println( "Added thread: " + t );
}
}
public static void addThread( Runnable r, String s )
{
Thread t = new Thread( r, s );
t.start();
addThread( t );
}
public static void stopThread( Thread t )
{
synchronized( threads )
{
for( int i = 0; i < threads.size(); i++ )
{
if( threads.get( i ) == t )
{
threads.get( i ).interrupt();
threads.remove( i );
}
}
}
}
public static void stopAllThreads()
{
boolean stopped = false;
while( stopped == false )
{
System.out.println( "Stopping all threads" );
synchronized( threads )
{
System.out.println( "Threads being stopped: " + threads.size() );
for( int i = 0; i < threads.size(); i++ )
{
System.out.println( "Stopping: " + threads.get( i ) );
threads.get( i ).interrupt();
}
threads.clear();
stopped = true;
}
}
}
private static ArrayList< Thread > threads = null;
private static Thread threadsMonitor = null;
private class ThreadsMonitor implements Runnable
{
public ThreadsMonitor()
{
}
public void run()
{
while( true )
{
synchronized( threads )
{
for( int i = 0; i < threads.size(); i++ )
{
if( !threads.get( i ).isAlive() )
{
threads.get( i ).interrupt();
threads.remove( i );
}
synchronized( threadsMonitor )
{
try
{
threadsMonitor.wait( 5000 );
}
catch( InterruptedException e )
{
threadsMonitor.interrupted();
return;
}
}
}
}
}
}
}
}
最佳答案
很难看清整体情况,但要了解一些一般要点甚至更一般的建议。
While attempting to debug it, I put in the while loop to try and force the method to eventually run the for loop, but all that happens is it outputs "Stopping all threads" and then I never see anything else
while( !stopped )中的stopAllThreads是多余的,因为它永远不会循环。AddThread中,您有这个private boolean running = true;
volatile。 Java多线程编码的整个领域都处理数据可见性,而volatile是用于确保正确性的工具之一。java.util.concurrent软件包。尽管了解基础知识也非常重要,但是此软件包具有许多非常聪明的人设计的非常有用的结构,这些结构将解决许多常见的并发问题。java.util.concurrent包一起工作的同一小组编写的。 for( int i = 0; i < threads.size(); i++ )
{
if( !threads.get( i ).isAlive() )
{
threads.get( i ).interrupt();
threads.remove( i );
}
}
关于java - Java多线程帮助,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/3885657/
我真的很习惯使用Ruby编写以下代码:my_hash={}my_hash['test']=1Java中对应的数据结构是什么? 最佳答案 HashMapmap=newHashMap();map.put("test",1);我假设? 关于java-等价于Java中的RubyHash,我们在StackOverflow上找到一个类似的问题: https://stackoverflow.com/questions/22737685/
我收到这个错误:RuntimeError(自动加载常量Apps时检测到循环依赖当我使用多线程时。下面是我的代码。为什么会这样?我尝试多线程的原因是因为我正在编写一个HTML抓取应用程序。对Nokogiri::HTML(open())的调用是一个同步阻塞调用,需要1秒才能返回,我有100,000多个页面要访问,所以我试图运行多个线程来解决这个问题。有更好的方法吗?classToolsController0)app.website=array.join(',')putsapp.websiteelseapp.website="NONE"endapp.saveapps=Apps.order("
我正在阅读SandiMetz的POODR,并且遇到了一个我不太了解的编码原则。这是代码:classBicycleattr_reader:size,:chain,:tire_sizedefinitialize(args={})@size=args[:size]||1@chain=args[:chain]||2@tire_size=args[:tire_size]||3post_initialize(args)endendclassMountainBike此代码将为其各自的属性输出1,2,3,4,5。我不明白的是查找方法。当一辆山地自行车被实例化时,因为它没有自己的initialize方法
只是想确保我理解了事情。据我目前收集到的信息,Cucumber只是一个“包装器”,或者是一种通过将事物分类为功能和步骤来组织测试的好方法,其中实际的单元测试处于步骤阶段。它允许您根据事物的工作方式组织您的测试。对吗? 最佳答案 有点。它是一种组织测试的方式,但不仅如此。它的行为就像最初的Rails集成测试一样,但更易于使用。这里最大的好处是您的session在整个Scenario中保持透明。关于Cucumber的另一件事是您(应该)从使用您的代码的浏览器或客户端的角度进行测试。如果您愿意,您可以使用步骤来构建对象和设置状态,但通常您
我正在尝试使用boilerpipe来自JRuby。我看过guide从JRuby调用Java,并成功地将它与另一个Java包一起使用,但无法弄清楚为什么同样的东西不能用于boilerpipe。我正在尝试基本上从JRuby中执行与此Java等效的操作:URLurl=newURL("http://www.example.com/some-location/index.html");Stringtext=ArticleExtractor.INSTANCE.getText(url);在JRuby中试过这个:require'java'url=java.net.URL.new("http://www
我只想对我一直在思考的这个问题有其他意见,例如我有classuser_controller和classuserclassUserattr_accessor:name,:usernameendclassUserController//dosomethingaboutanythingaboutusersend问题是我的User类中是否应该有逻辑user=User.newuser.do_something(user1)oritshouldbeuser_controller=UserController.newuser_controller.do_something(user1,user2)我
什么是ruby的rack或python的Java的wsgi?还有一个路由库。 最佳答案 来自Python标准PEP333:Bycontrast,althoughJavahasjustasmanywebapplicationframeworksavailable,Java's"servlet"APImakesitpossibleforapplicationswrittenwithanyJavawebapplicationframeworktoruninanywebserverthatsupportstheservletAPI.ht
这篇文章是继上一篇文章“Observability:从零开始创建Java微服务并监控它(一)”的续篇。在上一篇文章中,我们讲述了如何创建一个Javaweb应用,并使用Filebeat来收集应用所生成的日志。在今天的文章中,我来详述如何收集应用的指标,使用APM来监控应用并监督web服务的在线情况。源码可以在地址 https://github.com/liu-xiao-guo/java_observability 进行下载。摄入指标指标被视为可以随时更改的时间点值。当前请求的数量可以改变任何毫秒。你可能有1000个请求的峰值,然后一切都回到一个请求。这也意味着这些指标可能不准确,你还想提取最小/
HashMap中为什么引入红黑树,而不是AVL树呢1.概述开始学习这个知识点之前我们需要知道,在JDK1.8以及之前,针对HashMap有什么不同。JDK1.7的时候,HashMap的底层实现是数组+链表JDK1.8的时候,HashMap的底层实现是数组+链表+红黑树我们要思考一个问题,为什么要从链表转为红黑树呢。首先先让我们了解下链表有什么不好???2.链表上述的截图其实就是链表的结构,我们来看下链表的增删改查的时间复杂度增:因为链表不是线性结构,所以每次添加的时候,只需要移动一个节点,所以可以理解为复杂度是N(1)删:算法时间复杂度跟增保持一致查:既然是非线性结构,所以查询某一个节点的时候
遍历文件夹我们通常是使用递归进行操作,这种方式比较简单,也比较容易理解。本文为大家介绍另一种不使用递归的方式,由于没有使用递归,只用到了循环和集合,所以效率更高一些!一、使用递归遍历文件夹整体思路1、使用File封装初始目录,2、打印这个目录3、获取这个目录下所有的子文件和子目录的数组。4、遍历这个数组,取出每个File对象4-1、如果File是否是一个文件,打印4-2、否则就是一个目录,递归调用代码实现publicclassSearchFile{publicstaticvoidmain(String[]args){//初始目录Filedir=newFile("d:/Dev");Datebeg